diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2f162734c..e5a17c222 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.67.1" + ".": "0.68.0" } diff --git a/.stats.yml b/.stats.yml index 2f8268ab1..33e553ff2 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 94 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-63df0e3eb49d4874724f380b650693d90e071a41748bc163e93236b72a342883.yml -openapi_spec_hash: eb5df67593bd1c4a5c8d1082f24d73fb -config_hash: 95facb8cef59b5a1b05763b871bf6a4b +configured_endpoints: 97 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-5f33221208c1febba343daf570f73a5086f150a9b128df045ebddc3fe2c86607.yml +openapi_spec_hash: 0aea07130ddbe43a665a13a68231e2ca +config_hash: 2363f563f42501d2b1587a4f64bdccaf diff --git a/CHANGELOG.md b/CHANGELOG.md index 72f638bea..aa33efe7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## 0.68.0 (2025-11-19) + +Full Changelog: [v0.67.1...v0.68.0](https://github.com/runloopai/api-client-ts/compare/v0.67.1...v0.68.0) + +### Features + +* **blueprint:** adds queued state ([c8f5e0b](https://github.com/runloopai/api-client-ts/commit/c8f5e0b01cbd2fd573403b7d9b61816efce03b1f)) +* **blueprints:** Cleanup the BuildContext API ([#6407](https://github.com/runloopai/api-client-ts/issues/6407))\n\nTest ([8bd1c44](https://github.com/runloopai/api-client-ts/commit/8bd1c4468565effadc66b8524594daa5761938a4)) +* **blueprints:** prevent deletion of blueprints with dependent snapshots ([f52eb9a](https://github.com/runloopai/api-client-ts/commit/f52eb9aedc5d9317a2ab27952c13b0f2b2172339)) +* **devbox:** adding devbox execution std out / err last n lines ([#643](https://github.com/runloopai/api-client-ts/issues/643)) ([71de54c](https://github.com/runloopai/api-client-ts/commit/71de54c13bca60f3057e8c8ed2b8e5e531fffc9f)) +* **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. ([0ee5067](https://github.com/runloopai/api-client-ts/commit/0ee50676c734c536a8d1b5c25ef19d154da1f121)) +* **streaming:** harden SSE timeout recovery ([#645](https://github.com/runloopai/api-client-ts/issues/645)) ([cb249a7](https://github.com/runloopai/api-client-ts/commit/cb249a7d2c854a28e3932f35b2ad98dd30c8737b)) + + +### Bug Fixes + +* **file-mount:** client side validation for file_mount size checks ([#639](https://github.com/runloopai/api-client-ts/issues/639)) ([30e7123](https://github.com/runloopai/api-client-ts/commit/30e712315740c393c21dbfe34e4d2611dca0d0dc)) +* **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 ([5f8b203](https://github.com/runloopai/api-client-ts/commit/5f8b2031aa38ff9a87e3554c9e5100189ea448e2)) + ## 0.67.1 (2025-11-05) Full Changelog: [v0.67.0...v0.67.1](https://github.com/runloopai/api-client-ts/compare/v0.67.0...v0.67.1) diff --git a/api.md b/api.md index 06ab35263..54c2fa2f5 100644 --- a/api.md +++ b/api.md @@ -4,6 +4,7 @@ Types: - AfterIdle - AgentMountParameters +- AgentSource - CodeMountParameters - LaunchParameters - Mount @@ -41,6 +42,20 @@ Methods: - client.benchmarks.runs.complete(id) -> BenchmarkRunView - client.benchmarks.runs.listScenarioRuns(id, { ...params }) -> ScenarioRunViewsBenchmarkRunsCursorIDPage +# Agents + +Types: + +- AgentCreateParameters +- AgentListView +- AgentView + +Methods: + +- client.agents.create({ ...params }) -> AgentView +- client.agents.retrieve(id) -> AgentView +- client.agents.list({ ...params }) -> AgentViewsAgentsCursorIDPage + # Blueprints Types: diff --git a/package.json b/package.json index f4e357d24..a55f2cd82 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@runloop/api-client", - "version": "0.67.1", + "version": "0.68.0", "description": "The official TypeScript library for the Runloop API", "author": "Runloop ", "types": "dist/sdk.d.ts", diff --git a/src/index.ts b/src/index.ts index 9730acfd6..605dbe9d6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,8 @@ import * as Core from './core'; import * as Errors from './error'; import * as Pagination from './pagination'; import { + type AgentsCursorIDPageParams, + AgentsCursorIDPageResponse, type BenchmarkRunsCursorIDPageParams, BenchmarkRunsCursorIDPageResponse, type BenchmarksCursorIDPageParams, @@ -28,6 +30,15 @@ import { } from './pagination'; import * as Uploads from './uploads'; import * as API from './resources/index'; +import { + AgentCreateParameters, + AgentCreateParams, + AgentListParams, + AgentListView, + AgentView, + AgentViewsAgentsCursorIDPage, + Agents, +} from './resources/agents'; import { BlueprintBuildFromInspectionParameters, BlueprintBuildLog, @@ -289,6 +300,7 @@ export class Runloop extends Core.APIClient { } benchmarks: API.Benchmarks = new API.Benchmarks(this); + agents: API.Agents = new API.Agents(this); blueprints: API.Blueprints = new API.Blueprints(this); devboxes: API.Devboxes = new API.Devboxes(this); scenarios: API.Scenarios = new API.Scenarios(this); @@ -341,6 +353,8 @@ export class Runloop extends Core.APIClient { Runloop.Benchmarks = Benchmarks; Runloop.BenchmarkViewsBenchmarksCursorIDPage = BenchmarkViewsBenchmarksCursorIDPage; +Runloop.Agents = Agents; +Runloop.AgentViewsAgentsCursorIDPage = AgentViewsAgentsCursorIDPage; Runloop.Blueprints = Blueprints; Runloop.BlueprintViewsBlueprintsCursorIDPage = BlueprintViewsBlueprintsCursorIDPage; Runloop.Devboxes = Devboxes; @@ -387,6 +401,12 @@ export declare namespace Runloop { type BenchmarksCursorIDPageResponse as BenchmarksCursorIDPageResponse, }; + export import AgentsCursorIDPage = Pagination.AgentsCursorIDPage; + export { + type AgentsCursorIDPageParams as AgentsCursorIDPageParams, + type AgentsCursorIDPageResponse as AgentsCursorIDPageResponse, + }; + export import BenchmarkRunsCursorIDPage = Pagination.BenchmarkRunsCursorIDPage; export { type BenchmarkRunsCursorIDPageParams as BenchmarkRunsCursorIDPageParams, @@ -434,6 +454,16 @@ export declare namespace Runloop { type BenchmarkStartRunParams as BenchmarkStartRunParams, }; + export { + Agents as Agents, + type AgentCreateParameters as AgentCreateParameters, + type AgentListView as AgentListView, + type AgentView as AgentView, + AgentViewsAgentsCursorIDPage as AgentViewsAgentsCursorIDPage, + type AgentCreateParams as AgentCreateParams, + type AgentListParams as AgentListParams, + }; + export { Blueprints as Blueprints, type BlueprintBuildFromInspectionParameters as BlueprintBuildFromInspectionParameters, @@ -561,6 +591,7 @@ export declare namespace Runloop { export type AfterIdle = API.AfterIdle; export type AgentMountParameters = API.AgentMountParameters; + export type AgentSource = API.AgentSource; export type CodeMountParameters = API.CodeMountParameters; export type LaunchParameters = API.LaunchParameters; export type Mount = API.Mount; diff --git a/src/pagination.ts b/src/pagination.ts index e77136509..7d867de79 100644 --- a/src/pagination.ts +++ b/src/pagination.ts @@ -372,6 +372,80 @@ export class BenchmarksCursorIDPage } } +export interface AgentsCursorIDPageResponse { + agents: Array; + + has_more: boolean; + + total_count: number; +} + +export interface AgentsCursorIDPageParams { + starting_after?: string; + + limit?: number; +} + +export class AgentsCursorIDPage + extends AbstractPage + implements AgentsCursorIDPageResponse +{ + agents: Array; + + has_more: boolean; + + total_count: number; + + constructor( + client: APIClient, + response: Response, + body: AgentsCursorIDPageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.agents = body.agents || []; + this.has_more = body.has_more || false; + this.total_count = body.total_count || 0; + } + + getPaginatedItems(): Item[] { + return this.agents ?? []; + } + + override hasNextPage(): boolean { + if (this.has_more === false) { + return false; + } + + return super.hasNextPage(); + } + + // @deprecated Please use `nextPageInfo()` instead + nextPageParams(): Partial | null { + const info = this.nextPageInfo(); + if (!info) return null; + if ('params' in info) return info.params; + const params = Object.fromEntries(info.url.searchParams); + if (!Object.keys(params).length) return null; + return params; + } + + nextPageInfo(): PageInfo | null { + const agents = this.getPaginatedItems(); + if (!agents.length) { + return null; + } + + const id = agents[agents.length - 1]?.id; + if (!id) { + return null; + } + + return { params: { starting_after: id } }; + } +} + export interface BenchmarkRunsCursorIDPageResponse { runs: Array; diff --git a/src/resources/agents.ts b/src/resources/agents.ts new file mode 100644 index 000000000..4c090332b --- /dev/null +++ b/src/resources/agents.ts @@ -0,0 +1,156 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../resource'; +import { isRequestOptions } from '../core'; +import * as Core from '../core'; +import * as Shared from './shared'; +import { AgentsCursorIDPage, type AgentsCursorIDPageParams } from '../pagination'; + +export class Agents extends APIResource { + /** + * Create a new Agent with a name and optional public visibility. The Agent will be + * assigned a unique ID. + */ + create(body: AgentCreateParams, options?: Core.RequestOptions): Core.APIPromise { + return this._client.post('/v1/agents', { body, ...options }); + } + + /** + * Retrieve a specific Agent by its unique identifier. + */ + retrieve(id: string, options?: Core.RequestOptions): Core.APIPromise { + return this._client.get(`/v1/agents/${id}`, options); + } + + /** + * List all Agents for the authenticated account with pagination support. + */ + list( + query?: AgentListParams, + options?: Core.RequestOptions, + ): Core.PagePromise; + list(options?: Core.RequestOptions): Core.PagePromise; + list( + query: AgentListParams | Core.RequestOptions = {}, + options?: Core.RequestOptions, + ): Core.PagePromise { + if (isRequestOptions(query)) { + return this.list({}, query); + } + return this._client.getAPIList('/v1/agents', AgentViewsAgentsCursorIDPage, { query, ...options }); + } +} + +export class AgentViewsAgentsCursorIDPage extends AgentsCursorIDPage {} + +/** + * Parameters for creating a new Agent. + */ +export interface AgentCreateParameters { + /** + * The name of the Agent. + */ + name: string; + + /** + * The source configuration for the Agent. + */ + source?: Shared.AgentSource | null; +} + +/** + * A paginated list of Agents. + */ +export interface AgentListView { + /** + * The list of Agents. + */ + agents: Array; + + /** + * Whether there are more Agents to fetch. + */ + has_more: boolean; + + /** + * The count of remaining Agents. + */ + remaining_count: number; + + /** + * The total count of Agents. + */ + total_count: number; +} + +/** + * An Agent represents a registered AI agent entity. + */ +export interface AgentView { + /** + * The unique identifier of the Agent. + */ + id: string; + + /** + * The creation time of the Agent (Unix timestamp milliseconds). + */ + create_time_ms: number; + + /** + * Whether the Agent is publicly accessible. + */ + is_public: boolean; + + /** + * The name of the Agent. + */ + name: string; + + /** + * The source configuration for the Agent. + */ + source?: Shared.AgentSource | null; +} + +export interface AgentCreateParams { + /** + * The name of the Agent. + */ + name: string; + + /** + * The source configuration for the Agent. + */ + source?: Shared.AgentSource | null; +} + +export interface AgentListParams extends AgentsCursorIDPageParams { + /** + * Filter agents by public visibility. + */ + is_public?: boolean; + + /** + * Filter agents by name (partial match supported). + */ + name?: string; + + /** + * Search by agent ID or name. + */ + search?: string; +} + +Agents.AgentViewsAgentsCursorIDPage = AgentViewsAgentsCursorIDPage; + +export declare namespace Agents { + export { + type AgentCreateParameters as AgentCreateParameters, + type AgentListView as AgentListView, + type AgentView as AgentView, + AgentViewsAgentsCursorIDPage as AgentViewsAgentsCursorIDPage, + type AgentCreateParams as AgentCreateParams, + type AgentListParams as AgentListParams, + }; +} diff --git a/src/resources/blueprints.ts b/src/resources/blueprints.ts index c91f7a4c1..993c3f0d0 100644 --- a/src/resources/blueprints.ts +++ b/src/resources/blueprints.ts @@ -156,7 +156,9 @@ export class Blueprints extends APIResource { } /** - * Delete a previously created Blueprint. + * Delete a previously created Blueprint. If a blueprint has dependent snapshots, + * it cannot be deleted. You can find them by querying: GET + * /v1/devboxes/disk_snapshots?source_blueprint_id={blueprint_id}. */ delete(id: string, options?: Core.RequestOptions): Core.APIPromise { return this._client.post(`/v1/blueprints/${id}/delete`, options); @@ -316,6 +318,11 @@ export interface BlueprintBuildParameters { */ build_args?: { [key: string]: string } | null; + /** + * A build context backed by an Object. + */ + build_context?: BlueprintBuildParameters.BuildContext | null; + /** * A list of code mounts to be included in the Blueprint. */ @@ -341,6 +348,14 @@ export interface BlueprintBuildParameters { */ metadata?: { [key: string]: string } | null; + /** + * (Optional) Map of named build contexts to attach to the Blueprint build, where + * the keys are the name used when referencing the contexts in a Dockerfile. See + * Docker buildx additional contexts for details: + * https://docs.docker.com/reference/cli/docker/buildx/build/#build-context + */ + named_build_contexts?: { [key: string]: BlueprintBuildParameters.NamedBuildContexts } | null; + /** * (Optional) Map of mount IDs/environment variable names to secret names. Secrets * will be available to commands during the build. Secrets are NOT stored in the @@ -363,6 +378,30 @@ export interface BlueprintBuildParameters { } export namespace BlueprintBuildParameters { + /** + * A build context backed by an Object. + */ + export interface BuildContext { + /** + * The ID of an object, whose contents are to be used as a build context. + */ + object_id: string; + + type: 'object'; + } + + /** + * A build context backed by an Object. + */ + export interface NamedBuildContexts { + /** + * The ID of an object, whose contents are to be used as a build context. + */ + object_id: string; + + type: 'object'; + } + export interface Service { /** * The image of the container service. @@ -468,7 +507,7 @@ export interface BlueprintView { /** * The status of the Blueprint build. */ - status: 'provisioning' | 'building' | 'failed' | 'build_complete'; + status: 'queued' | 'provisioning' | 'building' | 'failed' | 'build_complete'; /** * The ID of the base Blueprint. @@ -601,6 +640,11 @@ export interface BlueprintCreateParams { */ build_args?: { [key: string]: string } | null; + /** + * A build context backed by an Object. + */ + build_context?: BlueprintCreateParams.BuildContext | null; + /** * A list of code mounts to be included in the Blueprint. */ @@ -626,6 +670,14 @@ export interface BlueprintCreateParams { */ metadata?: { [key: string]: string } | null; + /** + * (Optional) Map of named build contexts to attach to the Blueprint build, where + * the keys are the name used when referencing the contexts in a Dockerfile. See + * Docker buildx additional contexts for details: + * https://docs.docker.com/reference/cli/docker/buildx/build/#build-context + */ + named_build_contexts?: { [key: string]: BlueprintCreateParams.NamedBuildContexts } | null; + /** * (Optional) Map of mount IDs/environment variable names to secret names. Secrets * will be available to commands during the build. Secrets are NOT stored in the @@ -648,6 +700,30 @@ export interface BlueprintCreateParams { } export namespace BlueprintCreateParams { + /** + * A build context backed by an Object. + */ + export interface BuildContext { + /** + * The ID of an object, whose contents are to be used as a build context. + */ + object_id: string; + + type: 'object'; + } + + /** + * A build context backed by an Object. + */ + export interface NamedBuildContexts { + /** + * The ID of an object, whose contents are to be used as a build context. + */ + object_id: string; + + type: 'object'; + } + export interface Service { /** * The image of the container service. @@ -779,6 +855,11 @@ export interface BlueprintPreviewParams { */ build_args?: { [key: string]: string } | null; + /** + * A build context backed by an Object. + */ + build_context?: BlueprintPreviewParams.BuildContext | null; + /** * A list of code mounts to be included in the Blueprint. */ @@ -804,6 +885,14 @@ export interface BlueprintPreviewParams { */ metadata?: { [key: string]: string } | null; + /** + * (Optional) Map of named build contexts to attach to the Blueprint build, where + * the keys are the name used when referencing the contexts in a Dockerfile. See + * Docker buildx additional contexts for details: + * https://docs.docker.com/reference/cli/docker/buildx/build/#build-context + */ + named_build_contexts?: { [key: string]: BlueprintPreviewParams.NamedBuildContexts } | null; + /** * (Optional) Map of mount IDs/environment variable names to secret names. Secrets * will be available to commands during the build. Secrets are NOT stored in the @@ -826,6 +915,30 @@ export interface BlueprintPreviewParams { } export namespace BlueprintPreviewParams { + /** + * A build context backed by an Object. + */ + export interface BuildContext { + /** + * The ID of an object, whose contents are to be used as a build context. + */ + object_id: string; + + type: 'object'; + } + + /** + * A build context backed by an Object. + */ + export interface NamedBuildContexts { + /** + * The ID of an object, whose contents are to be used as a build context. + */ + object_id: string; + + type: 'object'; + } + export interface Service { /** * The image of the container service. diff --git a/src/resources/devboxes/devboxes.ts b/src/resources/devboxes/devboxes.ts index 8fc9b444f..3c69eb4f0 100644 --- a/src/resources/devboxes/devboxes.ts +++ b/src/resources/devboxes/devboxes.ts @@ -342,8 +342,8 @@ export class Devboxes extends APIResource { } /** - * List all snapshots of a Devbox while optionally filtering by Devbox ID and - * metadata. + * List all snapshots of a Devbox while optionally filtering by Devbox ID, source + * Blueprint ID, and metadata. */ listDiskSnapshots( query?: DevboxListDiskSnapshotsParams, @@ -703,6 +703,11 @@ export interface DevboxSnapshotView { * (Optional) The custom name of the snapshot. */ name?: string | null; + + /** + * (Optional) The source Blueprint ID this snapshot was created from. + */ + source_blueprint_id?: string | null; } export interface DevboxTunnelView { @@ -825,7 +830,7 @@ export namespace DevboxView { * provisioning: Runloop is allocating and booting the necessary infrastructure * resources. initializing: Runloop defined boot scripts are running to enable the * environment for interaction. running: The Devbox is ready for interaction. - * suspending: The Devbox disk is being snaphsotted and as part of suspension. + * suspending: The Devbox disk is being snapshotted as part of suspension. * suspended: The Devbox disk is saved and no more active compute is being used for * the Devbox. resuming: The Devbox disk is being loaded as part of booting a * suspended Devbox. failure: The Devbox failed as part of booting or running user @@ -842,6 +847,9 @@ export namespace DevboxView { | 'failure' | 'shutdown'; + /** + * The time the status change occurred + */ transition_time_ms?: unknown; } } @@ -1088,6 +1096,11 @@ export interface DevboxListDiskSnapshotsParams extends DiskSnapshotsCursorIDPage * Filter snapshots by metadata key with multiple possible values (OR condition). */ 'metadata[key][in]'?: string; + + /** + * Source Blueprint ID to filter snapshots by. + */ + source_blueprint_id?: string; } export interface DevboxReadFileContentsParams { diff --git a/src/resources/devboxes/disk-snapshots.ts b/src/resources/devboxes/disk-snapshots.ts index 0658e7bff..2741771b8 100644 --- a/src/resources/devboxes/disk-snapshots.ts +++ b/src/resources/devboxes/disk-snapshots.ts @@ -31,8 +31,8 @@ export class DiskSnapshots extends APIResource { } /** - * List all snapshots of a Devbox while optionally filtering by Devbox ID and - * metadata. + * List all snapshots of a Devbox while optionally filtering by Devbox ID, source + * Blueprint ID, and metadata. */ list( query?: DiskSnapshotListParams, @@ -109,7 +109,7 @@ export interface DevboxSnapshotAsyncStatusView { /** * The current status of the snapshot operation. */ - status: 'in_progress' | 'error' | 'complete'; + status: 'in_progress' | 'error' | 'complete' | 'deleted'; /** * Error message if the operation failed. @@ -157,6 +157,11 @@ export interface DiskSnapshotListParams extends DiskSnapshotsCursorIDPageParams * Filter snapshots by metadata key with multiple possible values (OR condition). */ 'metadata[key][in]'?: string; + + /** + * Source Blueprint ID to filter snapshots by. + */ + source_blueprint_id?: string; } export declare namespace DiskSnapshots { diff --git a/src/resources/index.ts b/src/resources/index.ts index ec552a29d..b07a85e3e 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -1,6 +1,15 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export * from './shared'; +export { + AgentViewsAgentsCursorIDPage, + Agents, + type AgentCreateParameters, + type AgentListView, + type AgentView, + type AgentCreateParams, + type AgentListParams, +} from './agents'; export { BenchmarkRunViewsBenchmarkRunsCursorIDPage, BenchmarkViewsBenchmarksCursorIDPage, diff --git a/src/resources/objects.ts b/src/resources/objects.ts index 0fa423dee..db536b314 100644 --- a/src/resources/objects.ts +++ b/src/resources/objects.ts @@ -126,6 +126,12 @@ export interface ObjectCreateParameters { * User defined metadata to attach to the object for organization. */ metadata?: { [key: string]: string } | null; + + /** + * Optional lifetime of the object in milliseconds, after which the object is + * automatically deleted. Time starts ticking after the object is created. + */ + ttl_ms?: number | null; } /** @@ -190,7 +196,12 @@ export interface ObjectView { /** * The current state of the Object. */ - state: string; + state: 'UPLOADING' | 'READ_ONLY' | 'DELETED' | 'ERROR'; + + /** + * The time after which the Object will be deleted in milliseconds since epoch. + */ + delete_after_time_ms?: number | null; /** * The size of the Object content in bytes (null until uploaded). @@ -218,16 +229,22 @@ export interface ObjectCreateParams { * User defined metadata to attach to the object for organization. */ metadata?: { [key: string]: string } | null; + + /** + * Optional lifetime of the object in milliseconds, after which the object is + * automatically deleted. Time starts ticking after the object is created. + */ + ttl_ms?: number | null; } export interface ObjectListParams extends ObjectsCursorIDPageParams { /** - * Filter objects by content type. + * Filter storage objects by content type. */ - content_type?: string; + content_type?: 'unspecified' | 'text' | 'binary' | 'gzip' | 'tar' | 'tgz'; /** - * Filter objects by name (partial match supported). + * Filter storage objects by name (partial match supported). */ name?: string; @@ -237,9 +254,9 @@ export interface ObjectListParams extends ObjectsCursorIDPageParams { search?: string; /** - * Filter objects by state (UPLOADING, READ_ONLY, DELETED). + * Filter storage objects by state. */ - state?: string; + state?: 'UPLOADING' | 'READ_ONLY' | 'DELETED' | 'ERROR'; } export interface ObjectDeleteParams {} @@ -255,12 +272,12 @@ export interface ObjectDownloadParams { export interface ObjectListPublicParams extends ObjectsCursorIDPageParams { /** - * Filter objects by content type. + * Filter storage objects by content type. */ - content_type?: string; + content_type?: 'unspecified' | 'text' | 'binary' | 'gzip' | 'tar' | 'tgz'; /** - * Filter objects by name (partial match supported). + * Filter storage objects by name (partial match supported). */ name?: string; @@ -270,9 +287,9 @@ export interface ObjectListPublicParams extends ObjectsCursorIDPageParams { search?: string; /** - * Filter objects by state (UPLOADING, READ_ONLY, DELETED). + * Filter storage objects by state. */ - state?: string; + state?: 'UPLOADING' | 'READ_ONLY' | 'DELETED' | 'ERROR'; } Objects.ObjectViewsObjectsCursorIDPage = ObjectViewsObjectsCursorIDPage; diff --git a/src/resources/shared.ts b/src/resources/shared.ts index 1b0f68ae3..aa9529894 100644 --- a/src/resources/shared.ts +++ b/src/resources/shared.ts @@ -14,17 +14,145 @@ export interface AfterIdle { export interface AgentMountParameters { /** - * The ID of the agent to mount. + * The ID of the agent to mount. Either agent_id or name must be set. */ - agent_id: string; + agent_id: string | null; + + /** + * The name of the agent to mount. Returns the most recent agent with a matching + * name if no agent id string provided. Either agent id or name must be set + */ + agent_name: string | null; type: 'agent_mount'; /** - * Optional path to mount the agent on the Devbox. Required for git and object - * agents. Use absolute path (e.g., /home/user/agent) + * Path to mount the agent on the Devbox. Required for git and object agents. Use + * absolute path (e.g., /home/user/agent) */ agent_path?: string | null; + + /** + * Optional auth token for private repositories. Only used for git agents. + */ + auth_token?: string | null; +} + +/** + * Agent source configuration. + */ +export interface AgentSource { + /** + * Source type: npm, pip, object, or git + */ + type: string; + + /** + * Git source configuration + */ + git?: AgentSource.Git | null; + + /** + * NPM source configuration + */ + npm?: AgentSource.Npm | null; + + /** + * Object store source configuration + */ + object?: AgentSource.Object | null; + + /** + * Pip source configuration + */ + pip?: AgentSource.Pip | null; +} + +export namespace AgentSource { + /** + * Git source configuration + */ + export interface Git { + /** + * Git repository URL + */ + repository: string; + + /** + * Setup commands to run after cloning + */ + agent_setup?: Array | null; + + /** + * Optional Git ref (branch/tag/commit), defaults to main/HEAD + */ + ref?: string | null; + } + + /** + * NPM source configuration + */ + export interface Npm { + /** + * NPM package name + */ + package_name: string; + + /** + * Setup commands to run after installation + */ + agent_setup?: Array | null; + + /** + * NPM version constraint + */ + npm_version?: string | null; + + /** + * NPM registry URL + */ + registry_url?: string | null; + } + + /** + * Object store source configuration + */ + export interface Object { + /** + * Object ID + */ + object_id: string; + + /** + * Setup commands to run after unpacking + */ + agent_setup?: Array | null; + } + + /** + * Pip source configuration + */ + export interface Pip { + /** + * Pip package name + */ + package_name: string; + + /** + * Setup commands to run after installation + */ + agent_setup?: Array | null; + + /** + * Pip version constraint + */ + pip_version?: string | null; + + /** + * Pip registry URL + */ + registry_url?: string | null; + } } export interface CodeMountParameters { diff --git a/src/sdk.ts b/src/sdk.ts index 391dd0e4f..62c9d474c 100644 --- a/src/sdk.ts +++ b/src/sdk.ts @@ -490,7 +490,17 @@ export class StorageObjectOps { } } -export default RunloopSDK; +// @deprecated Use {@link RunloopSDK} instead. +/** + * @deprecated Use {@link RunloopSDK} instead. + * @example + * ```typescript + * import { RunloopSDK } from '@runloop/api-client'; + * const sdk = new RunloopSDK(); + * const devbox = await sdk.devbox.create({ name: 'my-devbox' }); + * ``` + */ +export default Runloop; export declare namespace RunloopSDK { export { diff --git a/src/version.ts b/src/version.ts index 08f9854c4..71e734033 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '0.67.1'; // x-release-please-version +export const VERSION = '0.68.0'; // x-release-please-version diff --git a/tests/api-resources/agents.test.ts b/tests/api-resources/agents.test.ts new file mode 100644 index 000000000..6513f221d --- /dev/null +++ b/tests/api-resources/agents.test.ts @@ -0,0 +1,91 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import Runloop from '@runloop/api-client'; +import { Response } from 'node-fetch'; + +const client = new Runloop({ + bearerToken: 'My Bearer Token', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource agents', () => { + test('create: only required params', async () => { + const responsePromise = client.agents.create({ name: 'name' }); + 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('create: required and optional params', async () => { + const response = await client.agents.create({ + name: 'name', + source: { + type: 'type', + git: { repository: 'repository', agent_setup: ['string'], ref: 'ref' }, + npm: { + package_name: 'package_name', + agent_setup: ['string'], + npm_version: 'npm_version', + registry_url: 'registry_url', + }, + object: { object_id: 'object_id', agent_setup: ['string'] }, + pip: { + package_name: 'package_name', + agent_setup: ['string'], + pip_version: 'pip_version', + registry_url: 'registry_url', + }, + }, + }); + }); + + test('retrieve', async () => { + const responsePromise = client.agents.retrieve('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('retrieve: 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.agents.retrieve('id', { path: '/_stainless_unknown_path' })).rejects.toThrow( + Runloop.NotFoundError, + ); + }); + + test('list', async () => { + const responsePromise = client.agents.list(); + 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('list: 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.agents.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + Runloop.NotFoundError, + ); + }); + + test('list: 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.agents.list( + { is_public: true, limit: 0, name: 'name', search: 'search', starting_after: 'starting_after' }, + { path: '/_stainless_unknown_path' }, + ), + ).rejects.toThrow(Runloop.NotFoundError); + }); +}); diff --git a/tests/api-resources/blueprints.test.ts b/tests/api-resources/blueprints.test.ts index 057434657..545cd4903 100644 --- a/tests/api-resources/blueprints.test.ts +++ b/tests/api-resources/blueprints.test.ts @@ -26,6 +26,7 @@ describe('resource blueprints', () => { base_blueprint_id: 'base_blueprint_id', base_blueprint_name: 'base_blueprint_name', build_args: { foo: 'string' }, + build_context: { object_id: 'object_id', type: 'object' }, code_mounts: [ { repo_name: 'repo_name', @@ -50,6 +51,7 @@ describe('resource blueprints', () => { user_parameters: { uid: 0, username: 'username' }, }, metadata: { foo: 'string' }, + named_build_contexts: { foo: { object_id: 'object_id', type: 'object' } }, secrets: { foo: 'string' }, services: [ { @@ -254,6 +256,7 @@ describe('resource blueprints', () => { name: 'name', base_blueprint_name: 'base_blueprint_name', build_args: { foo: 'string' }, + build_context: { object_id: 'object_id', type: 'object' }, code_mounts: [ { repo_name: 'repo_name', @@ -278,6 +281,7 @@ describe('resource blueprints', () => { user_parameters: { uid: 0, username: 'username' }, }, metadata: { foo: 'string' }, + named_build_contexts: { foo: { object_id: 'object_id', type: 'object' } }, secrets: { foo: 'string' }, services: [ { diff --git a/tests/api-resources/devboxes/devboxes.test.ts b/tests/api-resources/devboxes/devboxes.test.ts index da9d3e8f5..30eb681b6 100644 --- a/tests/api-resources/devboxes/devboxes.test.ts +++ b/tests/api-resources/devboxes/devboxes.test.ts @@ -306,6 +306,7 @@ describe('resource devboxes', () => { limit: 0, 'metadata[key]': 'metadata[key]', 'metadata[key][in]': 'metadata[key][in]', + source_blueprint_id: 'source_blueprint_id', starting_after: 'starting_after', }, { path: '/_stainless_unknown_path' }, diff --git a/tests/api-resources/devboxes/disk-snapshots.test.ts b/tests/api-resources/devboxes/disk-snapshots.test.ts index 4bf75e15b..ba6f141a4 100644 --- a/tests/api-resources/devboxes/disk-snapshots.test.ts +++ b/tests/api-resources/devboxes/disk-snapshots.test.ts @@ -65,6 +65,7 @@ describe('resource diskSnapshots', () => { limit: 0, 'metadata[key]': 'metadata[key]', 'metadata[key][in]': 'metadata[key][in]', + source_blueprint_id: 'source_blueprint_id', starting_after: 'starting_after', }, { path: '/_stainless_unknown_path' }, diff --git a/tests/api-resources/objects.test.ts b/tests/api-resources/objects.test.ts index 403788636..dd8bef81e 100644 --- a/tests/api-resources/objects.test.ts +++ b/tests/api-resources/objects.test.ts @@ -25,6 +25,7 @@ describe('resource objects', () => { content_type: 'unspecified', name: 'name', metadata: { foo: 'string' }, + ttl_ms: 0, }); }); @@ -69,12 +70,12 @@ describe('resource objects', () => { await expect( client.objects.list( { - content_type: 'content_type', + content_type: 'unspecified', limit: 0, name: 'name', search: 'search', starting_after: 'starting_after', - state: 'state', + state: 'UPLOADING', }, { path: '/_stainless_unknown_path' }, ), @@ -165,12 +166,12 @@ describe('resource objects', () => { await expect( client.objects.listPublic( { - content_type: 'content_type', + content_type: 'unspecified', limit: 0, name: 'name', search: 'search', starting_after: 'starting_after', - state: 'state', + state: 'UPLOADING', }, { path: '/_stainless_unknown_path' }, ),