Skip to content

Commit 18a10ce

Browse files
release: 0.68.0 (#672)
* chore(package): drop Python 3.8 support * fix: compat with Python 3.14 * codegen metadata * codegen metadata * fix(compat): update signatures of `model_dump` and `model_dump_json` for Pydantic v1 * feat(blueprints): prevent deletion of blueprints with dependent snapshots * fix(snapshot): added "deleted" status to DevboxSnapshotStatus enum \n fix(storage-object): added ObjectState enum, fixed createObject() to appropriately type content_type and state as the respective enums * feat(object): Added ability to give objects a Time To Live, after which they are automatically deleted.\nfeat(blueprints): Added the ability to attach objects as build contexts that can be referenced in your Dockerfile. * chore(package): drop Python 3.8 support * feat(blueprints): Cleanup the BuildContext API (#6407)\n\nTest * release: 0.68.0 --------- Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
1 parent 25d8a01 commit 18a10ce

44 files changed

Lines changed: 1469 additions & 93 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.67.0"
2+
".": "0.68.0"
33
}

.stats.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 94
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-91cec4aeec2421487d5eeece4804ae3b8b47e22bdbb9fc7460feb64a8c10e42f.yml
3-
openapi_spec_hash: 3d8d782e2450d46b8ce6573bad488ea1
4-
config_hash: 95facb8cef59b5a1b05763b871bf6a4b
1+
configured_endpoints: 97
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-5f33221208c1febba343daf570f73a5086f150a9b128df045ebddc3fe2c86607.yml
3+
openapi_spec_hash: 0aea07130ddbe43a665a13a68231e2ca
4+
config_hash: 2363f563f42501d2b1587a4f64bdccaf

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
# Changelog
22

3+
## 0.68.0 (2025-11-19)
4+
5+
Full Changelog: [v0.67.0...v0.68.0](https://github.com/runloopai/api-client-python/compare/v0.67.0...v0.68.0)
6+
7+
### Features
8+
9+
* **blueprints:** Cleanup the BuildContext API ([#6407](https://github.com/runloopai/api-client-python/issues/6407))\n\nTest ([c87b986](https://github.com/runloopai/api-client-python/commit/c87b986e558ad3a0cca2ad1609b9833baf86fef8))
10+
* **blueprints:** prevent deletion of blueprints with dependent snapshots ([ce55350](https://github.com/runloopai/api-client-python/commit/ce55350d81f7f5ba3a3aff8faea88c0e1366cea9))
11+
* **object:** Added ability to give objects a Time To Live, after which they are automatically deleted.\nfeat(blueprints): Added the ability to attach objects as build contexts that can be referenced in your Dockerfile. ([f2bc83c](https://github.com/runloopai/api-client-python/commit/f2bc83c126696aea224bb5978294fc3362a94eeb))
12+
13+
14+
### Bug Fixes
15+
16+
* compat with Python 3.14 ([a52802a](https://github.com/runloopai/api-client-python/commit/a52802a6d12d96c3bf4bd670e77c9ec50d08b459))
17+
* **compat:** update signatures of `model_dump` and `model_dump_json` for Pydantic v1 ([50340b2](https://github.com/runloopai/api-client-python/commit/50340b20148f72cb645bba0bafde6f902e063425))
18+
* **snapshot:** added "deleted" status to DevboxSnapshotStatus enum \n fix(storage-object): added ObjectState enum, fixed createObject() to appropriately type content_type and state as the respective enums ([7c26593](https://github.com/runloopai/api-client-python/commit/7c265936088c074d00bd3c65b52dde5dcde3ccfb))
19+
20+
21+
### Chores
22+
23+
* **package:** drop Python 3.8 support ([07a0b8c](https://github.com/runloopai/api-client-python/commit/07a0b8c1825c78b0a6c30c2d374b82aced2f97d5))
24+
* **package:** drop Python 3.8 support ([d67abf1](https://github.com/runloopai/api-client-python/commit/d67abf1c52a089e192987a261e69219d60514bc3))
25+
326
## 0.67.0 (2025-11-14)
427

528
Full Changelog: [v0.66.1...v0.67.0](https://github.com/runloopai/api-client-python/compare/v0.66.1...v0.67.0)

api.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from runloop_api_client.types import (
55
AfterIdle,
66
AgentMountParameters,
7+
AgentSource,
78
CodeMountParameters,
89
LaunchParameters,
910
Mount,
@@ -47,6 +48,20 @@ Methods:
4748
- <code title="post /v1/benchmarks/runs/{id}/complete">client.benchmarks.runs.<a href="./src/runloop_api_client/resources/benchmarks/runs.py">complete</a>(id) -> <a href="./src/runloop_api_client/types/benchmark_run_view.py">BenchmarkRunView</a></code>
4849
- <code title="get /v1/benchmarks/runs/{id}/scenario_runs">client.benchmarks.runs.<a href="./src/runloop_api_client/resources/benchmarks/runs.py">list_scenario_runs</a>(id, \*\*<a href="src/runloop_api_client/types/benchmarks/run_list_scenario_runs_params.py">params</a>) -> <a href="./src/runloop_api_client/types/scenario_run_view.py">SyncBenchmarkRunsCursorIDPage[ScenarioRunView]</a></code>
4950

51+
# Agents
52+
53+
Types:
54+
55+
```python
56+
from runloop_api_client.types import AgentCreateParameters, AgentListView, AgentView
57+
```
58+
59+
Methods:
60+
61+
- <code title="post /v1/agents">client.agents.<a href="./src/runloop_api_client/resources/agents.py">create</a>(\*\*<a href="src/runloop_api_client/types/agent_create_params.py">params</a>) -> <a href="./src/runloop_api_client/types/agent_view.py">AgentView</a></code>
62+
- <code title="get /v1/agents/{id}">client.agents.<a href="./src/runloop_api_client/resources/agents.py">retrieve</a>(id) -> <a href="./src/runloop_api_client/types/agent_view.py">AgentView</a></code>
63+
- <code title="get /v1/agents">client.agents.<a href="./src/runloop_api_client/resources/agents.py">list</a>(\*\*<a href="src/runloop_api_client/types/agent_list_params.py">params</a>) -> <a href="./src/runloop_api_client/types/agent_view.py">SyncAgentsCursorIDPage[AgentView]</a></code>
64+
5065
# Blueprints
5166

5267
Types:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "runloop_api_client"
3-
version = "0.67.0"
3+
version = "0.68.0"
44
description = "The official Python library for the runloop API"
55
dynamic = ["readme"]
66
license = "MIT"

src/runloop_api_client/_client.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
)
3232

3333
if TYPE_CHECKING:
34-
from .resources import objects, secrets, devboxes, scenarios, benchmarks, blueprints, repositories
34+
from .resources import agents, objects, secrets, devboxes, scenarios, benchmarks, blueprints, repositories
35+
from .resources.agents import AgentsResource, AsyncAgentsResource
3536
from .resources.objects import ObjectsResource, AsyncObjectsResource
3637
from .resources.secrets import SecretsResource, AsyncSecretsResource
3738
from .resources.blueprints import BlueprintsResource, AsyncBlueprintsResource
@@ -106,6 +107,12 @@ def benchmarks(self) -> BenchmarksResource:
106107

107108
return BenchmarksResource(self)
108109

110+
@cached_property
111+
def agents(self) -> AgentsResource:
112+
from .resources.agents import AgentsResource
113+
114+
return AgentsResource(self)
115+
109116
@cached_property
110117
def blueprints(self) -> BlueprintsResource:
111118
from .resources.blueprints import BlueprintsResource
@@ -318,6 +325,12 @@ def benchmarks(self) -> AsyncBenchmarksResource:
318325

319326
return AsyncBenchmarksResource(self)
320327

328+
@cached_property
329+
def agents(self) -> AsyncAgentsResource:
330+
from .resources.agents import AsyncAgentsResource
331+
332+
return AsyncAgentsResource(self)
333+
321334
@cached_property
322335
def blueprints(self) -> AsyncBlueprintsResource:
323336
from .resources.blueprints import AsyncBlueprintsResource
@@ -479,6 +492,12 @@ def benchmarks(self) -> benchmarks.BenchmarksResourceWithRawResponse:
479492

480493
return BenchmarksResourceWithRawResponse(self._client.benchmarks)
481494

495+
@cached_property
496+
def agents(self) -> agents.AgentsResourceWithRawResponse:
497+
from .resources.agents import AgentsResourceWithRawResponse
498+
499+
return AgentsResourceWithRawResponse(self._client.agents)
500+
482501
@cached_property
483502
def blueprints(self) -> blueprints.BlueprintsResourceWithRawResponse:
484503
from .resources.blueprints import BlueprintsResourceWithRawResponse
@@ -528,6 +547,12 @@ def benchmarks(self) -> benchmarks.AsyncBenchmarksResourceWithRawResponse:
528547

529548
return AsyncBenchmarksResourceWithRawResponse(self._client.benchmarks)
530549

550+
@cached_property
551+
def agents(self) -> agents.AsyncAgentsResourceWithRawResponse:
552+
from .resources.agents import AsyncAgentsResourceWithRawResponse
553+
554+
return AsyncAgentsResourceWithRawResponse(self._client.agents)
555+
531556
@cached_property
532557
def blueprints(self) -> blueprints.AsyncBlueprintsResourceWithRawResponse:
533558
from .resources.blueprints import AsyncBlueprintsResourceWithRawResponse
@@ -577,6 +602,12 @@ def benchmarks(self) -> benchmarks.BenchmarksResourceWithStreamingResponse:
577602

578603
return BenchmarksResourceWithStreamingResponse(self._client.benchmarks)
579604

605+
@cached_property
606+
def agents(self) -> agents.AgentsResourceWithStreamingResponse:
607+
from .resources.agents import AgentsResourceWithStreamingResponse
608+
609+
return AgentsResourceWithStreamingResponse(self._client.agents)
610+
580611
@cached_property
581612
def blueprints(self) -> blueprints.BlueprintsResourceWithStreamingResponse:
582613
from .resources.blueprints import BlueprintsResourceWithStreamingResponse
@@ -626,6 +657,12 @@ def benchmarks(self) -> benchmarks.AsyncBenchmarksResourceWithStreamingResponse:
626657

627658
return AsyncBenchmarksResourceWithStreamingResponse(self._client.benchmarks)
628659

660+
@cached_property
661+
def agents(self) -> agents.AsyncAgentsResourceWithStreamingResponse:
662+
from .resources.agents import AsyncAgentsResourceWithStreamingResponse
663+
664+
return AsyncAgentsResourceWithStreamingResponse(self._client.agents)
665+
629666
@cached_property
630667
def blueprints(self) -> blueprints.AsyncBlueprintsResourceWithStreamingResponse:
631668
from .resources.blueprints import AsyncBlueprintsResourceWithStreamingResponse

src/runloop_api_client/_models.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import os
44
import inspect
5+
import weakref
56
from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, Optional, cast
67
from datetime import date, datetime
78
from typing_extensions import (
@@ -256,32 +257,41 @@ def model_dump(
256257
mode: Literal["json", "python"] | str = "python",
257258
include: IncEx | None = None,
258259
exclude: IncEx | None = None,
260+
context: Any | None = None,
259261
by_alias: bool | None = None,
260262
exclude_unset: bool = False,
261263
exclude_defaults: bool = False,
262264
exclude_none: bool = False,
265+
exclude_computed_fields: bool = False,
263266
round_trip: bool = False,
264267
warnings: bool | Literal["none", "warn", "error"] = True,
265-
context: dict[str, Any] | None = None,
266-
serialize_as_any: bool = False,
267268
fallback: Callable[[Any], Any] | None = None,
269+
serialize_as_any: bool = False,
268270
) -> dict[str, Any]:
269271
"""Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump
270272
271273
Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.
272274
273275
Args:
274276
mode: The mode in which `to_python` should run.
275-
If mode is 'json', the dictionary will only contain JSON serializable types.
276-
If mode is 'python', the dictionary may contain any Python objects.
277-
include: A list of fields to include in the output.
278-
exclude: A list of fields to exclude from the output.
277+
If mode is 'json', the output will only contain JSON serializable types.
278+
If mode is 'python', the output may contain non-JSON-serializable Python objects.
279+
include: A set of fields to include in the output.
280+
exclude: A set of fields to exclude from the output.
281+
context: Additional context to pass to the serializer.
279282
by_alias: Whether to use the field's alias in the dictionary key if defined.
280-
exclude_unset: Whether to exclude fields that are unset or None from the output.
281-
exclude_defaults: Whether to exclude fields that are set to their default value from the output.
282-
exclude_none: Whether to exclude fields that have a value of `None` from the output.
283-
round_trip: Whether to enable serialization and deserialization round-trip support.
284-
warnings: Whether to log warnings when invalid fields are encountered.
283+
exclude_unset: Whether to exclude fields that have not been explicitly set.
284+
exclude_defaults: Whether to exclude fields that are set to their default value.
285+
exclude_none: Whether to exclude fields that have a value of `None`.
286+
exclude_computed_fields: Whether to exclude computed fields.
287+
While this can be useful for round-tripping, it is usually recommended to use the dedicated
288+
`round_trip` parameter instead.
289+
round_trip: If True, dumped values should be valid as input for non-idempotent types such as Json[T].
290+
warnings: How to handle serialization errors. False/"none" ignores them, True/"warn" logs errors,
291+
"error" raises a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError].
292+
fallback: A function to call when an unknown value is encountered. If not provided,
293+
a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError] error is raised.
294+
serialize_as_any: Whether to serialize fields with duck-typing serialization behavior.
285295
286296
Returns:
287297
A dictionary representation of the model.
@@ -298,6 +308,8 @@ def model_dump(
298308
raise ValueError("serialize_as_any is only supported in Pydantic v2")
299309
if fallback is not None:
300310
raise ValueError("fallback is only supported in Pydantic v2")
311+
if exclude_computed_fields != False:
312+
raise ValueError("exclude_computed_fields is only supported in Pydantic v2")
301313
dumped = super().dict( # pyright: ignore[reportDeprecated]
302314
include=include,
303315
exclude=exclude,
@@ -314,15 +326,17 @@ def model_dump_json(
314326
self,
315327
*,
316328
indent: int | None = None,
329+
ensure_ascii: bool = False,
317330
include: IncEx | None = None,
318331
exclude: IncEx | None = None,
332+
context: Any | None = None,
319333
by_alias: bool | None = None,
320334
exclude_unset: bool = False,
321335
exclude_defaults: bool = False,
322336
exclude_none: bool = False,
337+
exclude_computed_fields: bool = False,
323338
round_trip: bool = False,
324339
warnings: bool | Literal["none", "warn", "error"] = True,
325-
context: dict[str, Any] | None = None,
326340
fallback: Callable[[Any], Any] | None = None,
327341
serialize_as_any: bool = False,
328342
) -> str:
@@ -354,6 +368,10 @@ def model_dump_json(
354368
raise ValueError("serialize_as_any is only supported in Pydantic v2")
355369
if fallback is not None:
356370
raise ValueError("fallback is only supported in Pydantic v2")
371+
if ensure_ascii != False:
372+
raise ValueError("ensure_ascii is only supported in Pydantic v2")
373+
if exclude_computed_fields != False:
374+
raise ValueError("exclude_computed_fields is only supported in Pydantic v2")
357375
return super().json( # type: ignore[reportDeprecated]
358376
indent=indent,
359377
include=include,
@@ -573,6 +591,9 @@ class CachedDiscriminatorType(Protocol):
573591
__discriminator__: DiscriminatorDetails
574592

575593

594+
DISCRIMINATOR_CACHE: weakref.WeakKeyDictionary[type, DiscriminatorDetails] = weakref.WeakKeyDictionary()
595+
596+
576597
class DiscriminatorDetails:
577598
field_name: str
578599
"""The name of the discriminator field in the variant class, e.g.
@@ -615,8 +636,9 @@ def __init__(
615636

616637

617638
def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any, ...]) -> DiscriminatorDetails | None:
618-
if isinstance(union, CachedDiscriminatorType):
619-
return union.__discriminator__
639+
cached = DISCRIMINATOR_CACHE.get(union)
640+
if cached is not None:
641+
return cached
620642

621643
discriminator_field_name: str | None = None
622644

@@ -669,7 +691,7 @@ def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any,
669691
discriminator_field=discriminator_field_name,
670692
discriminator_alias=discriminator_alias,
671693
)
672-
cast(CachedDiscriminatorType, union).__discriminator__ = details
694+
DISCRIMINATOR_CACHE.setdefault(union, details)
673695
return details
674696

675697

src/runloop_api_client/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

33
__title__ = "runloop_api_client"
4-
__version__ = "0.67.0" # x-release-please-version
4+
__version__ = "0.68.0" # x-release-please-version

0 commit comments

Comments
 (0)