diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 7840fde9a..4fcfdf7a7 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.8.1" + ".": "1.9.0" } diff --git a/.stats.yml b/.stats.yml index 44040dae9..e8c2e4563 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 117 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-8704a652545c3831c8b7e246ec17f1a626b59911eb5701ddc922ca6cae1c8d57.yml -openapi_spec_hash: e609bc5ed3fdce498bc7d16921bbba5e -config_hash: eb28692edd68a6ae95cf92af931c9976 +configured_endpoints: 118 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-dd0f43e15cb67179deaf86f83ae04c6fae4ff858ee33e82a3b89231566cdc5bb.yml +openapi_spec_hash: 569176c1c4f48efd25a44fa526fad9d1 +config_hash: cbda3692cb48ab8582a0df1674b9e5c8 diff --git a/CHANGELOG.md b/CHANGELOG.md index e55864f00..f7280b54a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # Changelog +## 1.9.0 (2026-02-25) + +Full Changelog: [v1.8.1...v1.9.0](https://github.com/runloopai/api-client-ts/compare/v1.8.1...v1.9.0) + +### Features + +* Add AI gateway and MCP gateway flags to network policy create ([#7638](https://github.com/runloopai/api-client-ts/issues/7638)) ([5542b72](https://github.com/runloopai/api-client-ts/commit/5542b727869a411b7828c2779f5f683e4c35f3ea)) + + +### Bug Fixes + +* **docs/contributing:** correct pnpm link command ([df98444](https://github.com/runloopai/api-client-ts/commit/df98444d096ae0fb8d737476ebb506122e3426b8)) +* **internal:** skip tests that depend on mock server ([284aac3](https://github.com/runloopai/api-client-ts/commit/284aac38f7f281f096ebb2bd4e5605df0db77a71)) +* workflow issues for npm stable tag and docs tar ([#721](https://github.com/runloopai/api-client-ts/issues/721)) ([2c5e7a4](https://github.com/runloopai/api-client-ts/commit/2c5e7a40f2b1cbcb73bb3ec17e2f4dd6e6e2ed6d)) + + +### Chores + +* Add archive method to stainless ([#7537](https://github.com/runloopai/api-client-ts/issues/7537)) ([b68ac03](https://github.com/runloopai/api-client-ts/commit/b68ac035f2d72bee47c2790c8c814e15e4ea4a1e)) +* allow specifying smoketests jest filter to workflow ([#722](https://github.com/runloopai/api-client-ts/issues/722)) ([b9d117b](https://github.com/runloopai/api-client-ts/commit/b9d117b23b5da12b38d7bc5e138079cedb40622b)) +* **documentation:** fixed bug in doc publishing ([#720](https://github.com/runloopai/api-client-ts/issues/720)) ([1eeb486](https://github.com/runloopai/api-client-ts/commit/1eeb486190d5184e7a9b8c363b68893c5492bf57)) +* **scenarios:** make scenario status enum instead of string ([#7552](https://github.com/runloopai/api-client-ts/issues/7552)) ([c5b244c](https://github.com/runloopai/api-client-ts/commit/c5b244ce0f502984420758c63e7a7c55760026f8)) +* update mock server docs ([875216d](https://github.com/runloopai/api-client-ts/commit/875216d63a50d030df6d5d3233a364a61b1b82b1)) + ## 1.8.1 (2026-02-19) Full Changelog: [v1.8.0...v1.8.1](https://github.com/runloopai/api-client-ts/compare/v1.8.0...v1.8.1) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 887fd5325..aa6af7e9d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -60,7 +60,7 @@ $ yarn link @runloop/api-client # With pnpm $ pnpm link --global $ cd ../my-package -$ pnpm link -—global @runloop/api-client +$ pnpm link --global @runloop/api-client ``` ## Running tests @@ -68,7 +68,7 @@ $ pnpm link -—global @runloop/api-client Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests. ```sh -$ npx prism mock path/to/your/openapi.yml +$ ./scripts/mock ``` ```sh diff --git a/api.md b/api.md index 2b28ba3df..18d40cbe0 100644 --- a/api.md +++ b/api.md @@ -245,6 +245,7 @@ Methods: - client.scenarios.retrieve(id) -> ScenarioView - client.scenarios.update(id, { ...params }) -> ScenarioView - client.scenarios.list({ ...params }) -> ScenarioViewsScenariosCursorIDPage +- client.scenarios.archive(id) -> ScenarioView - client.scenarios.listPublic({ ...params }) -> ScenarioViewsScenariosCursorIDPage - client.scenarios.startRun({ ...params }) -> ScenarioRunView diff --git a/package.json b/package.json index 7326f4966..9c0124b5b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@runloop/api-client", - "version": "1.8.1", + "version": "1.9.0", "description": "The official TypeScript library for the Runloop API", "author": "Runloop ", "types": "dist/sdk.d.ts", diff --git a/src/resources/devboxes/devboxes.ts b/src/resources/devboxes/devboxes.ts index 5777d7f47..5da3cb4c3 100644 --- a/src/resources/devboxes/devboxes.ts +++ b/src/resources/devboxes/devboxes.ts @@ -1024,6 +1024,12 @@ export interface TunnelView { */ create_time_ms: number; + /** + * When true, HTTP traffic through the tunnel counts as activity for idle lifecycle + * policies, resetting the idle timer. + */ + http_keep_alive: boolean; + /** * The encrypted tunnel key used to construct the tunnel URL. URL format: * https://{port}-{tunnel_key}.tunnel.runloop.{domain} @@ -1221,6 +1227,12 @@ export namespace DevboxCreateParams { * Authentication mode for the tunnel. Defaults to 'public' if not specified. */ auth_mode?: 'open' | 'authenticated' | null; + + /** + * When true, HTTP traffic through the tunnel counts as activity for idle lifecycle + * policies, resetting the idle timer. Defaults to true if not specified. + */ + http_keep_alive?: boolean | null; } } @@ -1271,6 +1283,12 @@ export interface DevboxEnableTunnelParams { * Authentication mode for the tunnel. Defaults to 'public' if not specified. */ auth_mode?: 'open' | 'authenticated' | null; + + /** + * When true, HTTP traffic through the tunnel counts as activity for idle lifecycle + * policies, resetting the idle timer. Defaults to true if not specified. + */ + http_keep_alive?: boolean | null; } /** diff --git a/src/resources/network-policies.ts b/src/resources/network-policies.ts index 4882ca2fa..823ba8ba5 100644 --- a/src/resources/network-policies.ts +++ b/src/resources/network-policies.ts @@ -88,6 +88,12 @@ export interface NetworkPolicyCreateParameters { */ name: string; + /** + * (Optional) If true, allows devbox egress to the AI credential gateway for + * credential proxying. Defaults to false. + */ + allow_ai_gateway?: boolean | null; + /** * (Optional) If true, all egress traffic is allowed (ALLOW_ALL policy). Defaults * to false. @@ -101,6 +107,12 @@ export interface NetworkPolicyCreateParameters { */ allow_devbox_to_devbox?: boolean | null; + /** + * (Optional) If true, allows devbox egress to the MCP hub for MCP server access. + * Defaults to false. + */ + allow_mcp_gateway?: boolean | null; + /** * (Optional) DNS-based allow list with wildcard support. Examples: ['github.com', * '*.npmjs.org']. @@ -138,6 +150,11 @@ export interface NetworkPolicyListView { * Parameters for updating an existing NetworkPolicy. All fields are optional. */ export interface NetworkPolicyUpdateParameters { + /** + * If true, allows devbox egress to the AI credential gateway. + */ + allow_ai_gateway?: boolean | null; + /** * If true, all egress traffic is allowed (ALLOW_ALL policy). */ @@ -148,6 +165,11 @@ export interface NetworkPolicyUpdateParameters { */ allow_devbox_to_devbox?: boolean | null; + /** + * If true, allows devbox egress to the MCP hub. + */ + allow_mcp_gateway?: boolean | null; + /** * Updated DNS-based allow list with wildcard support. Examples: ['github.com', * '*.npmjs.org']. @@ -206,6 +228,12 @@ export namespace NetworkPolicyView { * The egress rules for this policy. */ export interface Egress { + /** + * If true, allows devbox egress to the AI credential gateway for credential + * proxying. + */ + allow_ai_gateway: boolean; + /** * If true, all egress traffic is allowed and other fields are ignored. Used for * ALLOW_ALL policies. @@ -217,6 +245,11 @@ export namespace NetworkPolicyView { */ allow_devbox_to_devbox: boolean; + /** + * If true, allows devbox egress to the MCP hub for MCP server access. + */ + allow_mcp_gateway: boolean; + /** * DNS-based allow list with wildcard support. Examples: ['github.com', * '*.npmjs.org', 'api.openai.com']. Empty list with allow_all=false means no @@ -233,6 +266,12 @@ export interface NetworkPolicyCreateParams { */ name: string; + /** + * (Optional) If true, allows devbox egress to the AI credential gateway for + * credential proxying. Defaults to false. + */ + allow_ai_gateway?: boolean | null; + /** * (Optional) If true, all egress traffic is allowed (ALLOW_ALL policy). Defaults * to false. @@ -246,6 +285,12 @@ export interface NetworkPolicyCreateParams { */ allow_devbox_to_devbox?: boolean | null; + /** + * (Optional) If true, allows devbox egress to the MCP hub for MCP server access. + * Defaults to false. + */ + allow_mcp_gateway?: boolean | null; + /** * (Optional) DNS-based allow list with wildcard support. Examples: ['github.com', * '*.npmjs.org']. @@ -259,6 +304,11 @@ export interface NetworkPolicyCreateParams { } export interface NetworkPolicyUpdateParams { + /** + * If true, allows devbox egress to the AI credential gateway. + */ + allow_ai_gateway?: boolean | null; + /** * If true, all egress traffic is allowed (ALLOW_ALL policy). */ @@ -269,6 +319,11 @@ export interface NetworkPolicyUpdateParams { */ allow_devbox_to_devbox?: boolean | null; + /** + * If true, allows devbox egress to the MCP hub. + */ + allow_mcp_gateway?: boolean | null; + /** * Updated DNS-based allow list with wildcard support. Examples: ['github.com', * '*.npmjs.org']. diff --git a/src/resources/scenarios/scenarios.ts b/src/resources/scenarios/scenarios.ts index cb2b2a976..c3d6f4287 100644 --- a/src/resources/scenarios/scenarios.ts +++ b/src/resources/scenarios/scenarios.ts @@ -88,6 +88,14 @@ export class Scenarios extends APIResource { }); } + /** + * Archive a previously created Scenario. The scenario will no longer appear in + * list endpoints but can still be retrieved by ID. + */ + archive(id: string, options?: Core.RequestOptions): Core.APIPromise { + return this._client.post(`/v1/scenarios/${id}/archive`, options); + } + /** * List all public scenarios matching filter. */ @@ -422,9 +430,10 @@ export interface ScenarioView { scoring_contract: ScoringContract; /** - * The state of the scenario. + * Whether the scenario is active or archived. Archived scenarios are excluded from + * listings and cannot be updated. */ - status: string; + status: 'active' | 'archived'; /** * The Environment in which the Scenario is run. diff --git a/src/version.ts b/src/version.ts index 3c346f4fb..d6d803fa2 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '1.8.1'; // x-release-please-version +export const VERSION = '1.9.0'; // x-release-please-version diff --git a/tests/api-resources/devboxes/devboxes.test.ts b/tests/api-resources/devboxes/devboxes.test.ts index 4d17c0d19..b628d9dcf 100644 --- a/tests/api-resources/devboxes/devboxes.test.ts +++ b/tests/api-resources/devboxes/devboxes.test.ts @@ -74,7 +74,7 @@ describe('resource devboxes', () => { repo_connection_id: 'repo_connection_id', secrets: { foo: 'string' }, snapshot_id: 'snapshot_id', - tunnel: { auth_mode: 'open' }, + tunnel: { auth_mode: 'open', http_keep_alive: true }, }, { path: '/_stainless_unknown_path' }, ), @@ -240,7 +240,11 @@ describe('resource devboxes', () => { test('enableTunnel: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - client.devboxes.enableTunnel('id', { auth_mode: 'open' }, { path: '/_stainless_unknown_path' }), + client.devboxes.enableTunnel( + 'id', + { auth_mode: 'open', http_keep_alive: true }, + { path: '/_stainless_unknown_path' }, + ), ).rejects.toThrow(Runloop.NotFoundError); }); diff --git a/tests/api-resources/network-policies.test.ts b/tests/api-resources/network-policies.test.ts index 1a9291ac0..cb3a97df0 100644 --- a/tests/api-resources/network-policies.test.ts +++ b/tests/api-resources/network-policies.test.ts @@ -23,8 +23,10 @@ describe('resource networkPolicies', () => { test('create: required and optional params', async () => { const response = await client.networkPolicies.create({ name: 'name', + allow_ai_gateway: true, allow_all: true, allow_devbox_to_devbox: true, + allow_mcp_gateway: true, allowed_hostnames: ['string'], description: 'description', }); @@ -72,8 +74,10 @@ describe('resource networkPolicies', () => { client.networkPolicies.update( 'id', { + allow_ai_gateway: true, allow_all: true, allow_devbox_to_devbox: true, + allow_mcp_gateway: true, allowed_hostnames: ['string'], description: 'description', name: 'name', diff --git a/tests/api-resources/scenarios/runs.test.ts b/tests/api-resources/scenarios/runs.test.ts index 0997ff36f..8d5ce1629 100644 --- a/tests/api-resources/scenarios/runs.test.ts +++ b/tests/api-resources/scenarios/runs.test.ts @@ -98,7 +98,8 @@ describe('resource runs', () => { ); }); - test('downloadLogs: request options instead of params are passed correctly', async () => { + // Mock server doesn't support application/zip responses + test.skip('downloadLogs: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( client.scenarios.runs.downloadLogs('id', { path: '/_stainless_unknown_path' }), diff --git a/tests/api-resources/scenarios/scenarios.test.ts b/tests/api-resources/scenarios/scenarios.test.ts index 7603ee621..84e05196a 100644 --- a/tests/api-resources/scenarios/scenarios.test.ts +++ b/tests/api-resources/scenarios/scenarios.test.ts @@ -211,6 +211,24 @@ describe('resource scenarios', () => { ).rejects.toThrow(Runloop.NotFoundError); }); + test('archive', async () => { + const responsePromise = client.scenarios.archive('id'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + test('archive: request options instead of params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect(client.scenarios.archive('id', { path: '/_stainless_unknown_path' })).rejects.toThrow( + Runloop.NotFoundError, + ); + }); + test('listPublic', async () => { const responsePromise = client.scenarios.listPublic(); const rawResponse = await responsePromise.asResponse();