From de2e1707de516cfe5d98351bb1b4830e2dd6c7f0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 23:52:37 +0000 Subject: [PATCH 1/7] ci: pin GitHub Actions to commit SHAs Pin all GitHub Actions referenced in generated workflows (both first-party `actions/*` and third-party) to immutable commit SHAs. Updating pinned actions is now a deliberate codegen-side bump rather than implicit on every workflow run. --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/publish-pypi.yml | 2 +- .github/workflows/release-doctor.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 10b9a3a85..4e110b6be 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/runloop-python' && 'depot-ubuntu-24.04' || 'ubuntu-slim' }} if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install uv uses: runloopai/setup-uv@main @@ -46,7 +46,7 @@ jobs: id-token: write runs-on: ${{ github.repository == 'stainless-sdks/runloop-python' && 'depot-ubuntu-24.04' || 'ubuntu-slim' }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install uv uses: runloopai/setup-uv@main @@ -64,7 +64,7 @@ jobs: github.repository == 'stainless-sdks/runloop-python' && !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc - uses: actions/github-script@v8 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: core.setOutput('github_token', await core.getIDToken()); @@ -84,7 +84,7 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/runloop-python' && 'depot-ubuntu-24.04' || 'ubuntu-slim' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install uv uses: runloopai/setup-uv@main diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 7ec40f7d4..189e8027e 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-slim steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install uv uses: runloopai/setup-uv@main diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 364178039..0e5a99b97 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -12,7 +12,7 @@ jobs: if: github.repository == 'runloopai/api-client-python' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Check release environment run: | From c9c7c37c2a38f91142b0b28d1e5cbc183b8ee53e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 13 May 2026 21:48:10 +0000 Subject: [PATCH 2/7] feat(api): expose lifecycle_hooks on LaunchParameters lifecycle (#9115) --- .stats.yml | 4 +- .../types/shared/launch_parameters.py | 37 +++++++++++++++++-- .../types/shared_params/launch_parameters.py | 37 +++++++++++++++++-- tests/api_resources/test_benchmarks.py | 8 ++++ tests/api_resources/test_blueprints.py | 24 ++++++++++++ tests/api_resources/test_devboxes.py | 8 ++++ tests/api_resources/test_scenarios.py | 24 ++++++++++++ 7 files changed, 132 insertions(+), 10 deletions(-) diff --git a/.stats.yml b/.stats.yml index 75a9a5bb0..57d7d43d1 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 119 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai/runloop-6ec03cfc156036a0758aebc523b469f3007de431312c536c434efe795e1892e7.yml -openapi_spec_hash: 092761a0209e0950cfd8f262a981adb1 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai/runloop-d4505c10f86f4ad122bfbc2a82a519278d626ac399c9ef3780496d5d7d1b99b9.yml +openapi_spec_hash: b29dfd448505a0a3a6686202f606b8f7 config_hash: 06faf3176c48bf2b258730ce50809f0f diff --git a/src/runloop_api_client/types/shared/launch_parameters.py b/src/runloop_api_client/types/shared/launch_parameters.py index 6e74af438..3479a5421 100644 --- a/src/runloop_api_client/types/shared/launch_parameters.py +++ b/src/runloop_api_client/types/shared/launch_parameters.py @@ -6,7 +6,28 @@ from ..._models import BaseModel from .after_idle import AfterIdle -__all__ = ["LaunchParameters", "Lifecycle", "LifecycleResumeTriggers", "UserParameters"] +__all__ = ["LaunchParameters", "Lifecycle", "LifecycleLifecycleHooks", "LifecycleResumeTriggers", "UserParameters"] + + +class LifecycleLifecycleHooks(BaseModel): + """Optional lifecycle hooks. + + suspend_commands run through the suspend path before the Devbox suspends; see launch_commands for work on every startup. + """ + + suspend_commands: Optional[List[str]] = None + """Commands to run through the suspend path before the Devbox suspends (e.g. + + cleanup, quiesce daemons). + """ + + suspend_deadline_ms: Optional[int] = None + """Deadline in milliseconds for broker drain and suspend_commands during suspend. + + Defaults to 30000 ms and may not exceed 60000 ms. If exceeded, suspend work is + abandoned, the timeout is logged, and the Devbox still proceeds to suspend by + shutting down vmagent and killing the VM. + """ class LifecycleResumeTriggers(BaseModel): @@ -22,7 +43,7 @@ class LifecycleResumeTriggers(BaseModel): class Lifecycle(BaseModel): """Lifecycle configuration for idle and resume behavior. - Configure idle policy via lifecycle.after_idle (if both this and the top-level after_idle are set, they must match) and resume triggers via lifecycle.resume_triggers. + Configure idle policy via lifecycle.after_idle (if both this and the top-level after_idle are set, they must match), resume triggers via lifecycle.resume_triggers, and optional lifecycle hooks via lifecycle.lifecycle_hooks. """ after_idle: Optional[AfterIdle] = None @@ -32,6 +53,13 @@ class Lifecycle(BaseModel): value. Prefer this field for new integrations. """ + lifecycle_hooks: Optional[LifecycleLifecycleHooks] = None + """Optional lifecycle hooks. + + suspend_commands run through the suspend path before the Devbox suspends; see + launch_commands for work on every startup. + """ + resume_triggers: Optional[LifecycleResumeTriggers] = None """Triggers that can resume a suspended Devbox.""" @@ -93,8 +121,9 @@ class LaunchParameters(BaseModel): """Lifecycle configuration for idle and resume behavior. Configure idle policy via lifecycle.after_idle (if both this and the top-level - after_idle are set, they must match) and resume triggers via - lifecycle.resume_triggers. + after_idle are set, they must match), resume triggers via + lifecycle.resume_triggers, and optional lifecycle hooks via + lifecycle.lifecycle_hooks. """ network_policy_id: Optional[str] = None diff --git a/src/runloop_api_client/types/shared_params/launch_parameters.py b/src/runloop_api_client/types/shared_params/launch_parameters.py index 44ced4761..2f853eceb 100644 --- a/src/runloop_api_client/types/shared_params/launch_parameters.py +++ b/src/runloop_api_client/types/shared_params/launch_parameters.py @@ -8,7 +8,28 @@ from ..._types import SequenceNotStr from .after_idle import AfterIdle -__all__ = ["LaunchParameters", "Lifecycle", "LifecycleResumeTriggers", "UserParameters"] +__all__ = ["LaunchParameters", "Lifecycle", "LifecycleLifecycleHooks", "LifecycleResumeTriggers", "UserParameters"] + + +class LifecycleLifecycleHooks(TypedDict, total=False): + """Optional lifecycle hooks. + + suspend_commands run through the suspend path before the Devbox suspends; see launch_commands for work on every startup. + """ + + suspend_commands: Optional[SequenceNotStr[str]] + """Commands to run through the suspend path before the Devbox suspends (e.g. + + cleanup, quiesce daemons). + """ + + suspend_deadline_ms: Optional[int] + """Deadline in milliseconds for broker drain and suspend_commands during suspend. + + Defaults to 30000 ms and may not exceed 60000 ms. If exceeded, suspend work is + abandoned, the timeout is logged, and the Devbox still proceeds to suspend by + shutting down vmagent and killing the VM. + """ class LifecycleResumeTriggers(TypedDict, total=False): @@ -24,7 +45,7 @@ class LifecycleResumeTriggers(TypedDict, total=False): class Lifecycle(TypedDict, total=False): """Lifecycle configuration for idle and resume behavior. - Configure idle policy via lifecycle.after_idle (if both this and the top-level after_idle are set, they must match) and resume triggers via lifecycle.resume_triggers. + Configure idle policy via lifecycle.after_idle (if both this and the top-level after_idle are set, they must match), resume triggers via lifecycle.resume_triggers, and optional lifecycle hooks via lifecycle.lifecycle_hooks. """ after_idle: Optional[AfterIdle] @@ -34,6 +55,13 @@ class Lifecycle(TypedDict, total=False): value. Prefer this field for new integrations. """ + lifecycle_hooks: Optional[LifecycleLifecycleHooks] + """Optional lifecycle hooks. + + suspend_commands run through the suspend path before the Devbox suspends; see + launch_commands for work on every startup. + """ + resume_triggers: Optional[LifecycleResumeTriggers] """Triggers that can resume a suspended Devbox.""" @@ -95,8 +123,9 @@ class LaunchParameters(TypedDict, total=False): """Lifecycle configuration for idle and resume behavior. Configure idle policy via lifecycle.after_idle (if both this and the top-level - after_idle are set, they must match) and resume triggers via - lifecycle.resume_triggers. + after_idle are set, they must match), resume triggers via + lifecycle.resume_triggers, and optional lifecycle hooks via + lifecycle.lifecycle_hooks. """ network_policy_id: Optional[str] diff --git a/tests/api_resources/test_benchmarks.py b/tests/api_resources/test_benchmarks.py index 7612b34f2..0c1dd130f 100644 --- a/tests/api_resources/test_benchmarks.py +++ b/tests/api_resources/test_benchmarks.py @@ -304,6 +304,10 @@ def test_method_start_run_with_all_params(self, client: Runloop) -> None: "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, @@ -689,6 +693,10 @@ async def test_method_start_run_with_all_params(self, async_client: AsyncRunloop "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, diff --git a/tests/api_resources/test_blueprints.py b/tests/api_resources/test_blueprints.py index dd3e19fcb..acec702ab 100644 --- a/tests/api_resources/test_blueprints.py +++ b/tests/api_resources/test_blueprints.py @@ -70,6 +70,10 @@ def test_method_create_with_all_params(self, client: Runloop) -> None: "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, @@ -295,6 +299,10 @@ def test_method_create_from_inspection_with_all_params(self, client: Runloop) -> "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, @@ -464,6 +472,10 @@ def test_method_preview_with_all_params(self, client: Runloop) -> None: "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, @@ -576,6 +588,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunloop) - "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, @@ -801,6 +817,10 @@ async def test_method_create_from_inspection_with_all_params(self, async_client: "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, @@ -970,6 +990,10 @@ async def test_method_preview_with_all_params(self, async_client: AsyncRunloop) "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, diff --git a/tests/api_resources/test_devboxes.py b/tests/api_resources/test_devboxes.py index 97f51b915..dae981685 100644 --- a/tests/api_resources/test_devboxes.py +++ b/tests/api_resources/test_devboxes.py @@ -91,6 +91,10 @@ def test_method_create_with_all_params(self, client: Runloop) -> None: "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, @@ -1756,6 +1760,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunloop) - "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, diff --git a/tests/api_resources/test_scenarios.py b/tests/api_resources/test_scenarios.py index 9dd8c3e63..518618462 100644 --- a/tests/api_resources/test_scenarios.py +++ b/tests/api_resources/test_scenarios.py @@ -83,6 +83,10 @@ def test_method_create_with_all_params(self, client: Runloop) -> None: "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, @@ -228,6 +232,10 @@ def test_method_update_with_all_params(self, client: Runloop) -> None: "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, @@ -446,6 +454,10 @@ def test_method_start_run_with_all_params(self, client: Runloop) -> None: "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, @@ -564,6 +576,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunloop) - "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, @@ -709,6 +725,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncRunloop) - "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, @@ -927,6 +947,10 @@ async def test_method_start_run_with_all_params(self, async_client: AsyncRunloop "idle_time_seconds": 0, "on_idle": "shutdown", }, + "lifecycle_hooks": { + "suspend_commands": ["string"], + "suspend_deadline_ms": 0, + }, "resume_triggers": { "axon_event": True, "http": True, From 5d86ef5240920ba4b6de9e59456aea3c0971e3ef Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 13 May 2026 22:16:50 +0000 Subject: [PATCH 3/7] chore: Update stainless.yml, bump AGENTS.md to keep this updated (#9268) --- .stats.yml | 4 +- api.md | 3 + src/runloop_api_client/types/__init__.py | 3 + .../types/shared/__init__.py | 3 + .../types/shared/launch_parameters.py | 60 +------------------ .../types/shared/lifecycle_configuration.py | 34 +++++++++++ .../types/shared/lifecycle_hooks.py | 28 +++++++++ .../types/shared/resume_triggers.py | 17 ++++++ .../types/shared_params/__init__.py | 3 + .../types/shared_params/launch_parameters.py | 60 +------------------ .../shared_params/lifecycle_configuration.py | 36 +++++++++++ .../types/shared_params/lifecycle_hooks.py | 31 ++++++++++ .../types/shared_params/resume_triggers.py | 18 ++++++ 13 files changed, 184 insertions(+), 116 deletions(-) create mode 100644 src/runloop_api_client/types/shared/lifecycle_configuration.py create mode 100644 src/runloop_api_client/types/shared/lifecycle_hooks.py create mode 100644 src/runloop_api_client/types/shared/resume_triggers.py create mode 100644 src/runloop_api_client/types/shared_params/lifecycle_configuration.py create mode 100644 src/runloop_api_client/types/shared_params/lifecycle_hooks.py create mode 100644 src/runloop_api_client/types/shared_params/resume_triggers.py diff --git a/.stats.yml b/.stats.yml index 57d7d43d1..add3b32d7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 119 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai/runloop-d4505c10f86f4ad122bfbc2a82a519278d626ac399c9ef3780496d5d7d1b99b9.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai/runloop-70af693bc68f1ed5f2678a59d9ad3bb8a9e9bf8356fac4c3080cbd1a117819f8.yml openapi_spec_hash: b29dfd448505a0a3a6686202f606b8f7 -config_hash: 06faf3176c48bf2b258730ce50809f0f +config_hash: 444e00951b440bf92e7548b2807584a4 diff --git a/api.md b/api.md index 2f48b034e..30535e6f1 100644 --- a/api.md +++ b/api.md @@ -8,8 +8,11 @@ from runloop_api_client.types import ( BrokerMount, CodeMountParameters, LaunchParameters, + LifecycleConfiguration, + LifecycleHooks, Mount, ObjectMount, + ResumeTriggers, RunProfile, ) ``` diff --git a/src/runloop_api_client/types/__init__.py b/src/runloop_api_client/types/__init__.py index b28ef2790..428a5a7a2 100644 --- a/src/runloop_api_client/types/__init__.py +++ b/src/runloop_api_client/types/__init__.py @@ -10,8 +10,11 @@ AgentSource as AgentSource, BrokerMount as BrokerMount, ObjectMount as ObjectMount, + LifecycleHooks as LifecycleHooks, + ResumeTriggers as ResumeTriggers, LaunchParameters as LaunchParameters, CodeMountParameters as CodeMountParameters, + LifecycleConfiguration as LifecycleConfiguration, ) from .axon_view import AxonView as AxonView from .agent_view import AgentView as AgentView diff --git a/src/runloop_api_client/types/shared/__init__.py b/src/runloop_api_client/types/shared/__init__.py index 6f7d27818..5463ca25c 100644 --- a/src/runloop_api_client/types/shared/__init__.py +++ b/src/runloop_api_client/types/shared/__init__.py @@ -7,5 +7,8 @@ from .agent_source import AgentSource as AgentSource from .broker_mount import BrokerMount as BrokerMount from .object_mount import ObjectMount as ObjectMount +from .lifecycle_hooks import LifecycleHooks as LifecycleHooks +from .resume_triggers import ResumeTriggers as ResumeTriggers from .launch_parameters import LaunchParameters as LaunchParameters from .code_mount_parameters import CodeMountParameters as CodeMountParameters +from .lifecycle_configuration import LifecycleConfiguration as LifecycleConfiguration diff --git a/src/runloop_api_client/types/shared/launch_parameters.py b/src/runloop_api_client/types/shared/launch_parameters.py index 3479a5421..0f9b1a896 100644 --- a/src/runloop_api_client/types/shared/launch_parameters.py +++ b/src/runloop_api_client/types/shared/launch_parameters.py @@ -5,63 +5,9 @@ from ..._models import BaseModel from .after_idle import AfterIdle +from .lifecycle_configuration import LifecycleConfiguration -__all__ = ["LaunchParameters", "Lifecycle", "LifecycleLifecycleHooks", "LifecycleResumeTriggers", "UserParameters"] - - -class LifecycleLifecycleHooks(BaseModel): - """Optional lifecycle hooks. - - suspend_commands run through the suspend path before the Devbox suspends; see launch_commands for work on every startup. - """ - - suspend_commands: Optional[List[str]] = None - """Commands to run through the suspend path before the Devbox suspends (e.g. - - cleanup, quiesce daemons). - """ - - suspend_deadline_ms: Optional[int] = None - """Deadline in milliseconds for broker drain and suspend_commands during suspend. - - Defaults to 30000 ms and may not exceed 60000 ms. If exceeded, suspend work is - abandoned, the timeout is logged, and the Devbox still proceeds to suspend by - shutting down vmagent and killing the VM. - """ - - -class LifecycleResumeTriggers(BaseModel): - """Triggers that can resume a suspended Devbox.""" - - axon_event: Optional[bool] = None - """When true, axon events targeting a suspended Devbox will trigger a resume.""" - - http: Optional[bool] = None - """When true, HTTP traffic to a suspended Devbox via tunnel will trigger a resume.""" - - -class Lifecycle(BaseModel): - """Lifecycle configuration for idle and resume behavior. - - Configure idle policy via lifecycle.after_idle (if both this and the top-level after_idle are set, they must match), resume triggers via lifecycle.resume_triggers, and optional lifecycle hooks via lifecycle.lifecycle_hooks. - """ - - after_idle: Optional[AfterIdle] = None - """Configure Devbox lifecycle based on idle activity. - - If both this and the top-level after_idle are set, they must have the same - value. Prefer this field for new integrations. - """ - - lifecycle_hooks: Optional[LifecycleLifecycleHooks] = None - """Optional lifecycle hooks. - - suspend_commands run through the suspend path before the Devbox suspends; see - launch_commands for work on every startup. - """ - - resume_triggers: Optional[LifecycleResumeTriggers] = None - """Triggers that can resume a suspended Devbox.""" +__all__ = ["LaunchParameters", "UserParameters"] class UserParameters(BaseModel): @@ -117,7 +63,7 @@ class LaunchParameters(BaseModel): launch_commands: Optional[List[str]] = None """Set of commands to be run at launch time, before the entrypoint process is run.""" - lifecycle: Optional[Lifecycle] = None + lifecycle: Optional[LifecycleConfiguration] = None """Lifecycle configuration for idle and resume behavior. Configure idle policy via lifecycle.after_idle (if both this and the top-level diff --git a/src/runloop_api_client/types/shared/lifecycle_configuration.py b/src/runloop_api_client/types/shared/lifecycle_configuration.py new file mode 100644 index 000000000..4cbbb302f --- /dev/null +++ b/src/runloop_api_client/types/shared/lifecycle_configuration.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ..._models import BaseModel +from .after_idle import AfterIdle +from .lifecycle_hooks import LifecycleHooks +from .resume_triggers import ResumeTriggers + +__all__ = ["LifecycleConfiguration"] + + +class LifecycleConfiguration(BaseModel): + """Lifecycle configuration for Devbox idle and resume behavior. + + Configure idle policy via after_idle, resume triggers via resume_triggers, and optional lifecycle hooks via lifecycle_hooks. + """ + + after_idle: Optional[AfterIdle] = None + """Configure Devbox lifecycle based on idle activity. + + If both this and the top-level after_idle are set, they must have the same + value. Prefer this field for new integrations. + """ + + lifecycle_hooks: Optional[LifecycleHooks] = None + """Optional lifecycle hooks. + + suspend_commands run through the suspend path before the Devbox suspends; see + launch_commands for work on every startup. + """ + + resume_triggers: Optional[ResumeTriggers] = None + """Triggers that can resume a suspended Devbox.""" diff --git a/src/runloop_api_client/types/shared/lifecycle_hooks.py b/src/runloop_api_client/types/shared/lifecycle_hooks.py new file mode 100644 index 000000000..4a2a049c1 --- /dev/null +++ b/src/runloop_api_client/types/shared/lifecycle_hooks.py @@ -0,0 +1,28 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ..._models import BaseModel + +__all__ = ["LifecycleHooks"] + + +class LifecycleHooks(BaseModel): + """Lifecycle hooks for Devbox suspend. + + suspend_commands run sequentially as the configured Devbox user through the rage/vmagent suspend path before the Devbox suspends; failures are logged but do not block suspending. The suspend_deadline_ms budget defaults to 30000 ms, may not exceed 60000 ms, and covers broker drain plus suspend_commands. If the deadline is exceeded, suspend work is abandoned, the timeout is logged, and the Devbox still proceeds to suspend by shutting down vmagent and killing the VM. Resume hooks and resume deadline settings are persistence/internal only and hidden from the public API reference. launch_commands still run on every startup, including after resume. + """ + + suspend_commands: Optional[List[str]] = None + """Commands to run through the suspend path before the Devbox suspends (e.g. + + cleanup, quiesce daemons). + """ + + suspend_deadline_ms: Optional[int] = None + """Deadline in milliseconds for broker drain and suspend_commands during suspend. + + Defaults to 30000 ms and may not exceed 60000 ms. If exceeded, suspend work is + abandoned, the timeout is logged, and the Devbox still proceeds to suspend by + shutting down vmagent and killing the VM. + """ diff --git a/src/runloop_api_client/types/shared/resume_triggers.py b/src/runloop_api_client/types/shared/resume_triggers.py new file mode 100644 index 000000000..e2f3a4b3f --- /dev/null +++ b/src/runloop_api_client/types/shared/resume_triggers.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ..._models import BaseModel + +__all__ = ["ResumeTriggers"] + + +class ResumeTriggers(BaseModel): + """Triggers that can resume a suspended Devbox.""" + + axon_event: Optional[bool] = None + """When true, axon events targeting a suspended Devbox will trigger a resume.""" + + http: Optional[bool] = None + """When true, HTTP traffic to a suspended Devbox via tunnel will trigger a resume.""" diff --git a/src/runloop_api_client/types/shared_params/__init__.py b/src/runloop_api_client/types/shared_params/__init__.py index 6f7d27818..5463ca25c 100644 --- a/src/runloop_api_client/types/shared_params/__init__.py +++ b/src/runloop_api_client/types/shared_params/__init__.py @@ -7,5 +7,8 @@ from .agent_source import AgentSource as AgentSource from .broker_mount import BrokerMount as BrokerMount from .object_mount import ObjectMount as ObjectMount +from .lifecycle_hooks import LifecycleHooks as LifecycleHooks +from .resume_triggers import ResumeTriggers as ResumeTriggers from .launch_parameters import LaunchParameters as LaunchParameters from .code_mount_parameters import CodeMountParameters as CodeMountParameters +from .lifecycle_configuration import LifecycleConfiguration as LifecycleConfiguration diff --git a/src/runloop_api_client/types/shared_params/launch_parameters.py b/src/runloop_api_client/types/shared_params/launch_parameters.py index 2f853eceb..2a371c83b 100644 --- a/src/runloop_api_client/types/shared_params/launch_parameters.py +++ b/src/runloop_api_client/types/shared_params/launch_parameters.py @@ -7,63 +7,9 @@ from ..._types import SequenceNotStr from .after_idle import AfterIdle +from .lifecycle_configuration import LifecycleConfiguration -__all__ = ["LaunchParameters", "Lifecycle", "LifecycleLifecycleHooks", "LifecycleResumeTriggers", "UserParameters"] - - -class LifecycleLifecycleHooks(TypedDict, total=False): - """Optional lifecycle hooks. - - suspend_commands run through the suspend path before the Devbox suspends; see launch_commands for work on every startup. - """ - - suspend_commands: Optional[SequenceNotStr[str]] - """Commands to run through the suspend path before the Devbox suspends (e.g. - - cleanup, quiesce daemons). - """ - - suspend_deadline_ms: Optional[int] - """Deadline in milliseconds for broker drain and suspend_commands during suspend. - - Defaults to 30000 ms and may not exceed 60000 ms. If exceeded, suspend work is - abandoned, the timeout is logged, and the Devbox still proceeds to suspend by - shutting down vmagent and killing the VM. - """ - - -class LifecycleResumeTriggers(TypedDict, total=False): - """Triggers that can resume a suspended Devbox.""" - - axon_event: Optional[bool] - """When true, axon events targeting a suspended Devbox will trigger a resume.""" - - http: Optional[bool] - """When true, HTTP traffic to a suspended Devbox via tunnel will trigger a resume.""" - - -class Lifecycle(TypedDict, total=False): - """Lifecycle configuration for idle and resume behavior. - - Configure idle policy via lifecycle.after_idle (if both this and the top-level after_idle are set, they must match), resume triggers via lifecycle.resume_triggers, and optional lifecycle hooks via lifecycle.lifecycle_hooks. - """ - - after_idle: Optional[AfterIdle] - """Configure Devbox lifecycle based on idle activity. - - If both this and the top-level after_idle are set, they must have the same - value. Prefer this field for new integrations. - """ - - lifecycle_hooks: Optional[LifecycleLifecycleHooks] - """Optional lifecycle hooks. - - suspend_commands run through the suspend path before the Devbox suspends; see - launch_commands for work on every startup. - """ - - resume_triggers: Optional[LifecycleResumeTriggers] - """Triggers that can resume a suspended Devbox.""" +__all__ = ["LaunchParameters", "UserParameters"] class UserParameters(TypedDict, total=False): @@ -119,7 +65,7 @@ class LaunchParameters(TypedDict, total=False): launch_commands: Optional[SequenceNotStr[str]] """Set of commands to be run at launch time, before the entrypoint process is run.""" - lifecycle: Optional[Lifecycle] + lifecycle: Optional[LifecycleConfiguration] """Lifecycle configuration for idle and resume behavior. Configure idle policy via lifecycle.after_idle (if both this and the top-level diff --git a/src/runloop_api_client/types/shared_params/lifecycle_configuration.py b/src/runloop_api_client/types/shared_params/lifecycle_configuration.py new file mode 100644 index 000000000..0b53cfbcc --- /dev/null +++ b/src/runloop_api_client/types/shared_params/lifecycle_configuration.py @@ -0,0 +1,36 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import TypedDict + +from .after_idle import AfterIdle +from .lifecycle_hooks import LifecycleHooks +from .resume_triggers import ResumeTriggers + +__all__ = ["LifecycleConfiguration"] + + +class LifecycleConfiguration(TypedDict, total=False): + """Lifecycle configuration for Devbox idle and resume behavior. + + Configure idle policy via after_idle, resume triggers via resume_triggers, and optional lifecycle hooks via lifecycle_hooks. + """ + + after_idle: Optional[AfterIdle] + """Configure Devbox lifecycle based on idle activity. + + If both this and the top-level after_idle are set, they must have the same + value. Prefer this field for new integrations. + """ + + lifecycle_hooks: Optional[LifecycleHooks] + """Optional lifecycle hooks. + + suspend_commands run through the suspend path before the Devbox suspends; see + launch_commands for work on every startup. + """ + + resume_triggers: Optional[ResumeTriggers] + """Triggers that can resume a suspended Devbox.""" diff --git a/src/runloop_api_client/types/shared_params/lifecycle_hooks.py b/src/runloop_api_client/types/shared_params/lifecycle_hooks.py new file mode 100644 index 000000000..28b172e6f --- /dev/null +++ b/src/runloop_api_client/types/shared_params/lifecycle_hooks.py @@ -0,0 +1,31 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import TypedDict + +from ..._types import SequenceNotStr + +__all__ = ["LifecycleHooks"] + + +class LifecycleHooks(TypedDict, total=False): + """Lifecycle hooks for Devbox suspend. + + suspend_commands run sequentially as the configured Devbox user through the rage/vmagent suspend path before the Devbox suspends; failures are logged but do not block suspending. The suspend_deadline_ms budget defaults to 30000 ms, may not exceed 60000 ms, and covers broker drain plus suspend_commands. If the deadline is exceeded, suspend work is abandoned, the timeout is logged, and the Devbox still proceeds to suspend by shutting down vmagent and killing the VM. Resume hooks and resume deadline settings are persistence/internal only and hidden from the public API reference. launch_commands still run on every startup, including after resume. + """ + + suspend_commands: Optional[SequenceNotStr[str]] + """Commands to run through the suspend path before the Devbox suspends (e.g. + + cleanup, quiesce daemons). + """ + + suspend_deadline_ms: Optional[int] + """Deadline in milliseconds for broker drain and suspend_commands during suspend. + + Defaults to 30000 ms and may not exceed 60000 ms. If exceeded, suspend work is + abandoned, the timeout is logged, and the Devbox still proceeds to suspend by + shutting down vmagent and killing the VM. + """ diff --git a/src/runloop_api_client/types/shared_params/resume_triggers.py b/src/runloop_api_client/types/shared_params/resume_triggers.py new file mode 100644 index 000000000..02a89031a --- /dev/null +++ b/src/runloop_api_client/types/shared_params/resume_triggers.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import TypedDict + +__all__ = ["ResumeTriggers"] + + +class ResumeTriggers(TypedDict, total=False): + """Triggers that can resume a suspended Devbox.""" + + axon_event: Optional[bool] + """When true, axon events targeting a suspended Devbox will trigger a resume.""" + + http: Optional[bool] + """When true, HTTP traffic to a suspended Devbox via tunnel will trigger a resume.""" From 214629e9281c38ff75b5769e13b4b977a346bb04 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 15 May 2026 04:23:52 +0000 Subject: [PATCH 4/7] fix(mux): strip internal stub note from PTY OpenAPI descriptions (#9315) --- .stats.yml | 4 +- src/runloop_api_client/resources/pty.py | 64 ++++++++++--------------- 2 files changed, 26 insertions(+), 42 deletions(-) diff --git a/.stats.yml b/.stats.yml index add3b32d7..a96cfe31f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 119 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai/runloop-70af693bc68f1ed5f2678a59d9ad3bb8a9e9bf8356fac4c3080cbd1a117819f8.yml -openapi_spec_hash: b29dfd448505a0a3a6686202f606b8f7 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai/runloop-a248dcb8ee40eb7c0446077413996aa6a67b543a1f2a47272378641fa8791e7f.yml +openapi_spec_hash: 0636ec3e6ef760052c346ecaa8a4107d config_hash: 444e00951b440bf92e7548b2807584a4 diff --git a/src/runloop_api_client/resources/pty.py b/src/runloop_api_client/resources/pty.py index dc1a837b5..09158e0cc 100644 --- a/src/runloop_api_client/resources/pty.py +++ b/src/runloop_api_client/resources/pty.py @@ -68,22 +68,18 @@ def connect( effect. The response returns a PtyConnectView containing connect_url (a server-relative path to the WebSocket data plane), idle_ttl_seconds (how long this session is retained after the last client disconnects), and the resulting - cols/rows. The interactive byte stream itself is intentionally not modeled in - OpenAPI; see the controller-level documentation for the WebSocket close-code - conventions. The single-attach contract is enforced when a client opens the - WebSocket data plane, not on this bootstrap call: bootstrap always succeeds for - a valid session_name, even if another client is currently attached. Rejection of - a second concurrent attach happens at WebSocket upgrade time. If the active - client disconnects, the session is preserved for the idle TTL so a later connect - using the same session_name resumes the same shell. After the TTL expires, after - an explicit close control action, or after the underlying Devbox lifecycle - replaces the PTY process (such as through suspend/resume), a later request with - the same session_name creates a fresh PTY session without the previous shell - state. - - Documentation note: this operation is published from mux strictly as an OpenAPI - contract stub for the PTY service control plane. It is not evidence that mux - itself serves the interactive PTY transport. + cols/rows. The interactive terminal byte stream is exchanged over the WebSocket + data plane and is not modeled in this OpenAPI contract; clients should connect + to connect_url and exchange raw binary frames for terminal I/O. The + single-attach contract is enforced when a client opens the WebSocket data plane, + not on this bootstrap call: bootstrap always succeeds for a valid session_name, + even if another client is currently attached. Rejection of a second concurrent + attach happens at WebSocket upgrade time. If the active client disconnects, the + session is preserved for the idle TTL so a later connect using the same + session_name resumes the same shell. After the TTL expires, after an explicit + close control action, or after the underlying Devbox lifecycle replaces the PTY + process (such as through suspend/resume), a later request with the same + session_name creates a fresh PTY session without the previous shell state. Args: cols: Optional initial terminal width in character cells (1..=1000). Defaults to 80 @@ -158,10 +154,6 @@ def control( from the server's session cache. A subsequent connect with the same session_name will create a fresh PTY session. - Documentation note: this operation is published from mux strictly as an OpenAPI - contract stub for the PTY service control plane. It is not evidence that mux - itself serves the interactive PTY transport. - Args: extra_headers: Send extra headers @@ -241,22 +233,18 @@ async def connect( effect. The response returns a PtyConnectView containing connect_url (a server-relative path to the WebSocket data plane), idle_ttl_seconds (how long this session is retained after the last client disconnects), and the resulting - cols/rows. The interactive byte stream itself is intentionally not modeled in - OpenAPI; see the controller-level documentation for the WebSocket close-code - conventions. The single-attach contract is enforced when a client opens the - WebSocket data plane, not on this bootstrap call: bootstrap always succeeds for - a valid session_name, even if another client is currently attached. Rejection of - a second concurrent attach happens at WebSocket upgrade time. If the active - client disconnects, the session is preserved for the idle TTL so a later connect - using the same session_name resumes the same shell. After the TTL expires, after - an explicit close control action, or after the underlying Devbox lifecycle - replaces the PTY process (such as through suspend/resume), a later request with - the same session_name creates a fresh PTY session without the previous shell - state. - - Documentation note: this operation is published from mux strictly as an OpenAPI - contract stub for the PTY service control plane. It is not evidence that mux - itself serves the interactive PTY transport. + cols/rows. The interactive terminal byte stream is exchanged over the WebSocket + data plane and is not modeled in this OpenAPI contract; clients should connect + to connect_url and exchange raw binary frames for terminal I/O. The + single-attach contract is enforced when a client opens the WebSocket data plane, + not on this bootstrap call: bootstrap always succeeds for a valid session_name, + even if another client is currently attached. Rejection of a second concurrent + attach happens at WebSocket upgrade time. If the active client disconnects, the + session is preserved for the idle TTL so a later connect using the same + session_name resumes the same shell. After the TTL expires, after an explicit + close control action, or after the underlying Devbox lifecycle replaces the PTY + process (such as through suspend/resume), a later request with the same + session_name creates a fresh PTY session without the previous shell state. Args: cols: Optional initial terminal width in character cells (1..=1000). Defaults to 80 @@ -331,10 +319,6 @@ async def control( from the server's session cache. A subsequent connect with the same session_name will create a fresh PTY session. - Documentation note: this operation is published from mux strictly as an OpenAPI - contract stub for the PTY service control plane. It is not evidence that mux - itself serves the interactive PTY transport. - Args: extra_headers: Send extra headers From 5922abfd135589b229cb64ea23750d34fede857f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 13:58:42 +0000 Subject: [PATCH 5/7] feat: add reflex initiator type, hidden param (#9350) --- .stats.yml | 4 ++-- src/runloop_api_client/types/devbox_view.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index a96cfe31f..fe2d09b74 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 119 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai/runloop-a248dcb8ee40eb7c0446077413996aa6a67b543a1f2a47272378641fa8791e7f.yml -openapi_spec_hash: 0636ec3e6ef760052c346ecaa8a4107d +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai/runloop-2c6498f804f6a88977521c2b4b8700d8992235a01ffc965193d87acf8021683b.yml +openapi_spec_hash: cf32b83c81c8aa76f03dda8123b228b5 config_hash: 444e00951b440bf92e7548b2807584a4 diff --git a/src/runloop_api_client/types/devbox_view.py b/src/runloop_api_client/types/devbox_view.py index 068f180ad..83ffa8bec 100644 --- a/src/runloop_api_client/types/devbox_view.py +++ b/src/runloop_api_client/types/devbox_view.py @@ -100,7 +100,7 @@ class DevboxView(BaseModel): initiator_id: Optional[str] = None """The ID of the initiator that created the Devbox.""" - initiator_type: Optional[Literal["unknown", "api", "scenario", "scoring_validation"]] = None + initiator_type: Optional[Literal["unknown", "api", "scenario", "scoring_validation", "reflex"]] = None """The type of initiator that created the Devbox.""" mcp_specs: Optional[Dict[str, McpSpecs]] = None From 6601bd61991877a37f57a3fe61a4fcc28e4af24a Mon Sep 17 00:00:00 2001 From: tode-rl Date: Wed, 20 May 2026 09:56:22 -0700 Subject: [PATCH 6/7] Bridge integrated merge-conflict branch into next (#119) * ci: use Runloop GitHub action wrappers Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/publish-pypi.yml | 2 +- .github/workflows/release-doctor.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e110b6be..3db832c9d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/runloop-python' && 'depot-ubuntu-24.04' || 'ubuntu-slim' }} if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: runloopai/checkout@main - name: Install uv uses: runloopai/setup-uv@main @@ -46,7 +46,7 @@ jobs: id-token: write runs-on: ${{ github.repository == 'stainless-sdks/runloop-python' && 'depot-ubuntu-24.04' || 'ubuntu-slim' }} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: runloopai/checkout@main - name: Install uv uses: runloopai/setup-uv@main @@ -64,7 +64,7 @@ jobs: github.repository == 'stainless-sdks/runloop-python' && !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + uses: runloopai/github-script@main with: script: core.setOutput('github_token', await core.getIDToken()); @@ -84,7 +84,7 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/runloop-python' && 'depot-ubuntu-24.04' || 'ubuntu-slim' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: runloopai/checkout@main - name: Install uv uses: runloopai/setup-uv@main diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 189e8027e..7f148e54b 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-slim steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: runloopai/checkout@main - name: Install uv uses: runloopai/setup-uv@main diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 0e5a99b97..4ec1877db 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -12,7 +12,7 @@ jobs: if: github.repository == 'runloopai/api-client-python' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: runloopai/checkout@main - name: Check release environment run: | From 53a901e55c169944d710f014507da4efb23e9a0c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 20 May 2026 16:57:02 +0000 Subject: [PATCH 7/7] release: 1.22.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 19 +++++++++++++++++++ pyproject.toml | 2 +- src/runloop_api_client/_version.py | 2 +- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ba231b076..397c4203e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.21.0" + ".": "1.22.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 07431324c..dc89e8046 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## 1.22.0 (2026-05-20) + +Full Changelog: [v1.21.0...v1.22.0](https://github.com/runloopai/api-client-python/compare/v1.21.0...v1.22.0) + +### Features + +* add reflex initiator type, hidden param ([#9350](https://github.com/runloopai/api-client-python/issues/9350)) ([5922abf](https://github.com/runloopai/api-client-python/commit/5922abfd135589b229cb64ea23750d34fede857f)) +* **api:** expose lifecycle_hooks on LaunchParameters lifecycle ([#9115](https://github.com/runloopai/api-client-python/issues/9115)) ([c9c7c37](https://github.com/runloopai/api-client-python/commit/c9c7c37c2a38f91142b0b28d1e5cbc183b8ee53e)) + + +### Bug Fixes + +* **mux:** strip internal stub note from PTY OpenAPI descriptions ([#9315](https://github.com/runloopai/api-client-python/issues/9315)) ([214629e](https://github.com/runloopai/api-client-python/commit/214629e9281c38ff75b5769e13b4b977a346bb04)) + + +### Chores + +* Update stainless.yml, bump AGENTS.md to keep this updated ([#9268](https://github.com/runloopai/api-client-python/issues/9268)) ([5d86ef5](https://github.com/runloopai/api-client-python/commit/5d86ef5240920ba4b6de9e59456aea3c0971e3ef)) + ## 1.21.0 (2026-05-13) Full Changelog: [v1.20.3...v1.21.0](https://github.com/runloopai/api-client-python/compare/v1.20.3...v1.21.0) diff --git a/pyproject.toml b/pyproject.toml index c1f57fbd6..1b48f1988 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "runloop_api_client" -version = "1.21.0" +version = "1.22.0" description = "The official Python library for the runloop API" dynamic = ["readme"] license = "MIT" diff --git a/src/runloop_api_client/_version.py b/src/runloop_api_client/_version.py index e94914292..27a4b2948 100644 --- a/src/runloop_api_client/_version.py +++ b/src/runloop_api_client/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "runloop_api_client" -__version__ = "1.21.0" # x-release-please-version +__version__ = "1.22.0" # x-release-please-version