From fcf6b458f5dac025834a26b68098e175d0677916 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 23 Jul 2026 20:59:19 +0000 Subject: [PATCH 1/4] feat(api): add Model Router image and audio generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expose routed image and audio generate methods so SDKs can start jobs through a saved Model Router config without picking a model. - POST /v1/generate/image — route an image request via configId - POST /v1/generate/audio — route a speech/audio request via configId --- .stats.yml | 4 ++-- src/resources/routers.ts | 48 ++++++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/.stats.yml b/.stats.yml index 1f5c262..487bc72 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 57 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-33021d52306cc82f369d7ad1d391bc94fd5a377d4a92be35ece073b73f64a454.yml -openapi_spec_hash: d70a1ddd98e8aff8e1d298ff9c21b343 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-ab59188c11429113ed5e6696e1bb450cdebe393135fce9e1763be60fa0edd2cc.yml +openapi_spec_hash: ab95f9ae7163b960171e68f4ff95da4e config_hash: 6bdea3c3109ee75952f779d566c229ea diff --git a/src/resources/routers.ts b/src/resources/routers.ts index 65d0389..da7e6ea 100644 --- a/src/resources/routers.ts +++ b/src/resources/routers.ts @@ -119,8 +119,8 @@ export namespace RouterCreateResponse { /** * When mode is allow_new_except, ids are excluded; when allowlist_only, ids are - * the only allowed values. Each id must be a known public video model name - * (unknown ids are rejected on create/update). + * the only allowed values. Each id must be a known public video or image model + * name (unknown ids are rejected on create/update). */ models?: Settings.Models; @@ -145,8 +145,8 @@ export namespace RouterCreateResponse { /** * When mode is allow_new_except, ids are excluded; when allowlist_only, ids are - * the only allowed values. Each id must be a known public video model name - * (unknown ids are rejected on create/update). + * the only allowed values. Each id must be a known public video or image model + * name (unknown ids are rejected on create/update). */ export interface Models { ids: Array; @@ -215,8 +215,8 @@ export namespace RouterRetrieveResponse { /** * When mode is allow_new_except, ids are excluded; when allowlist_only, ids are - * the only allowed values. Each id must be a known public video model name - * (unknown ids are rejected on create/update). + * the only allowed values. Each id must be a known public video or image model + * name (unknown ids are rejected on create/update). */ models?: Settings.Models; @@ -241,8 +241,8 @@ export namespace RouterRetrieveResponse { /** * When mode is allow_new_except, ids are excluded; when allowlist_only, ids are - * the only allowed values. Each id must be a known public video model name - * (unknown ids are rejected on create/update). + * the only allowed values. Each id must be a known public video or image model + * name (unknown ids are rejected on create/update). */ export interface Models { ids: Array; @@ -311,8 +311,8 @@ export namespace RouterUpdateResponse { /** * When mode is allow_new_except, ids are excluded; when allowlist_only, ids are - * the only allowed values. Each id must be a known public video model name - * (unknown ids are rejected on create/update). + * the only allowed values. Each id must be a known public video or image model + * name (unknown ids are rejected on create/update). */ models?: Settings.Models; @@ -337,8 +337,8 @@ export namespace RouterUpdateResponse { /** * When mode is allow_new_except, ids are excluded; when allowlist_only, ids are - * the only allowed values. Each id must be a known public video model name - * (unknown ids are rejected on create/update). + * the only allowed values. Each id must be a known public video or image model + * name (unknown ids are rejected on create/update). */ export interface Models { ids: Array; @@ -410,8 +410,8 @@ export namespace RouterListResponse { /** * When mode is allow_new_except, ids are excluded; when allowlist_only, ids are - * the only allowed values. Each id must be a known public video model name - * (unknown ids are rejected on create/update). + * the only allowed values. Each id must be a known public video or image model + * name (unknown ids are rejected on create/update). */ models?: Settings.Models; @@ -436,8 +436,8 @@ export namespace RouterListResponse { /** * When mode is allow_new_except, ids are excluded; when allowlist_only, ids are - * the only allowed values. Each id must be a known public video model name - * (unknown ids are rejected on create/update). + * the only allowed values. Each id must be a known public video or image model + * name (unknown ids are rejected on create/update). */ export interface Models { ids: Array; @@ -489,8 +489,8 @@ export namespace RouterCreateParams { /** * When mode is allow_new_except, ids are excluded; when allowlist_only, ids are - * the only allowed values. Each id must be a known public video model name - * (unknown ids are rejected on create/update). + * the only allowed values. Each id must be a known public video or image model + * name (unknown ids are rejected on create/update). */ models?: Settings.Models; @@ -521,8 +521,8 @@ export namespace RouterCreateParams { /** * When mode is allow_new_except, ids are excluded; when allowlist_only, ids are - * the only allowed values. Each id must be a known public video model name - * (unknown ids are rejected on create/update). + * the only allowed values. Each id must be a known public video or image model + * name (unknown ids are rejected on create/update). */ export interface Models { ids: Array; @@ -563,8 +563,8 @@ export namespace RouterUpdateParams { /** * When mode is allow_new_except, ids are excluded; when allowlist_only, ids are - * the only allowed values. Each id must be a known public video model name - * (unknown ids are rejected on create/update). + * the only allowed values. Each id must be a known public video or image model + * name (unknown ids are rejected on create/update). */ models?: Settings.Models; @@ -595,8 +595,8 @@ export namespace RouterUpdateParams { /** * When mode is allow_new_except, ids are excluded; when allowlist_only, ids are - * the only allowed values. Each id must be a known public video model name - * (unknown ids are rejected on create/update). + * the only allowed values. Each id must be a known public video or image model + * name (unknown ids are rejected on create/update). */ export interface Models { ids: Array; From babe5528cccd693ec6e30f94db59ffa5b3e708c0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 23 Jul 2026 21:09:15 +0000 Subject: [PATCH 2/4] feat(api): expose generate image and audio endpoints --- .stats.yml | 6 +- api.md | 20 ++ src/resources/generate/audio.ts | 260 +++++++++++++++++++++ src/resources/generate/generate.ts | 20 ++ src/resources/generate/image.ts | 201 ++++++++++++++++ src/resources/generate/index.ts | 2 + tests/api-resources/generate/audio.test.ts | 38 +++ tests/api-resources/generate/image.test.ts | 39 ++++ 8 files changed, 583 insertions(+), 3 deletions(-) create mode 100644 src/resources/generate/audio.ts create mode 100644 src/resources/generate/image.ts create mode 100644 tests/api-resources/generate/audio.test.ts create mode 100644 tests/api-resources/generate/image.test.ts diff --git a/.stats.yml b/.stats.yml index 487bc72..5088d53 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 57 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-ab59188c11429113ed5e6696e1bb450cdebe393135fce9e1763be60fa0edd2cc.yml +configured_endpoints: 59 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runwayml/runwayml-a31e62dafc005582320d354e7aed335c8df690338ca539c055aa4a5637b9ad3b.yml openapi_spec_hash: ab95f9ae7163b960171e68f4ff95da4e -config_hash: 6bdea3c3109ee75952f779d566c229ea +config_hash: 95e64e640428abd4184a48762d9fd5f8 diff --git a/api.md b/api.md index 129ee27..9d5ac7d 100644 --- a/api.md +++ b/api.md @@ -141,6 +141,26 @@ Methods: - client.generate.video.create({ ...params }) -> VideoCreateResponse +## Image + +Types: + +- ImageCreateResponse + +Methods: + +- client.generate.image.create({ ...params }) -> ImageCreateResponse + +## Audio + +Types: + +- AudioCreateResponse + +Methods: + +- client.generate.audio.create({ ...params }) -> AudioCreateResponse + # Routers Types: diff --git a/src/resources/generate/audio.ts b/src/resources/generate/audio.ts new file mode 100644 index 0000000..57fdbff --- /dev/null +++ b/src/resources/generate/audio.ts @@ -0,0 +1,260 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../../core/resource'; +import { APIPromise } from '../../core/api-promise'; +import { RequestOptions } from '../../internal/request-options'; + +export class Audio extends APIResource { + /** + * Start an audio generation task using a saved Model Router config instead of + * naming a model. Set input.type to speech to speak promptText verbatim, or audio + * to generate audio described by promptText. + */ + create(body: AudioCreateParams, options?: RequestOptions): APIPromise { + return this._client.post('/v1/generate/audio', { body, ...options }); + } +} + +export interface AudioCreateResponse { + /** + * The ID of the created task. Poll GET /v1/tasks/:id for the result. + */ + id: string; + + /** + * Metadata describing which model the router selected and why. + */ + routing: AudioCreateResponse.Routing; +} + +export namespace AudioCreateResponse { + /** + * Metadata describing which model the router selected and why. + */ + export interface Routing { + /** + * The slug of the router config that was applied to this request. + */ + configId: string; + + /** + * Estimated cost, computed against current pricing. + */ + estimatedCost: Routing.EstimatedCost; + + /** + * The public name of the model the router selected. + */ + model: string; + + /** + * The provider of the selected model. + */ + provider: string; + + /** + * Request-side defaults resolved for the routing response. Not necessarily + * identical to prepared model options. + */ + resolvedInput: Routing.ResolvedInput; + + /** + * The resolved config settings the router used for this request. + */ + resolvedSettings: Routing.ResolvedSettings; + } + + export namespace Routing { + /** + * Estimated cost, computed against current pricing. + */ + export interface EstimatedCost { + /** + * Estimated cost of the generation in credits. + */ + credits: number; + } + + /** + * Request-side defaults resolved for the routing response. Not necessarily + * identical to prepared model options. + */ + export interface ResolvedInput { + /** + * The prompt mode the router routed for. + */ + type: 'speech' | 'audio'; + + /** + * How the selected model resolves the voice: the requested preset or + * reference-audio clone, the model default for voiceless speech, or none for + * general audio. + */ + voice: 'preset' | 'reference-audio' | 'default' | 'none'; + } + + /** + * The resolved config settings the router used for this request. + */ + export interface ResolvedSettings { + /** + * The single optimization preference the config selected, used as the soft + * weighting when scoring eligible models. + */ + optimizeFor: 'cost' | 'latency' | 'quality'; + + /** + * The applied maximum credits per generation for this request’s modality, or null + * if the config sets no ceiling. + */ + priceCeiling: number | null; + } + } +} + +export interface AudioCreateParams { + /** + * The slug of a saved Model Router config to route this request with. + */ + configId: string; + + /** + * Model-agnostic audio generation input. The router selects a model and maps these + * options to it. + */ + input: AudioCreateParams.Input; +} + +export namespace AudioCreateParams { + /** + * Model-agnostic audio generation input. The router selects a model and maps these + * options to it. + */ + export interface Input { + /** + * For `speech`, the words to speak. For `audio`, a description of the desired + * output. + */ + promptText: string; + + /** + * How promptText is interpreted: `speech` speaks it verbatim as a script; `audio` + * treats it as a description of the desired audio, which may combine speech, + * music, ambience, and sound effects. + */ + type: 'speech' | 'audio'; + + /** + * Desired output duration in seconds for `audio` generation. Models that cannot + * honor an explicit duration are excluded. + */ + duration?: number; + + /** + * When true, the `audio` output is designed to loop seamlessly. Models without + * loop support are excluded. + */ + loop?: boolean; + + /** + * Optional reference audio clips guiding `audio` generation, for models that + * support them. Reference each clip in promptText as @Audio1, @Audio2, and @Audio3 + * in order. + */ + referenceAudios?: Array; + + /** + * The voice to speak with. When omitted, models that support a default voice + * remain eligible. + */ + voice?: Input.Preset | Input.ReferenceAudio; + } + + export namespace Input { + export interface ReferenceAudio { + /** + * A HTTPS URL. + */ + uri: string; + } + + /** + * A preset voice. + */ + export interface Preset { + /** + * A Runway preset voice id. Choosing a preset routes only to models that support + * preset voices. + */ + presetId: + | 'Maya' + | 'Arjun' + | 'Serene' + | 'Bernard' + | 'Billy' + | 'Mark' + | 'Clint' + | 'Mabel' + | 'Chad' + | 'Leslie' + | 'Eleanor' + | 'Elias' + | 'Elliot' + | 'Grungle' + | 'Brodie' + | 'Sandra' + | 'Kirk' + | 'Kylie' + | 'Lara' + | 'Lisa' + | 'Malachi' + | 'Marlene' + | 'Martin' + | 'Miriam' + | 'Monster' + | 'Paula' + | 'Pip' + | 'Rusty' + | 'Ragnar' + | 'Xylar' + | 'Maggie' + | 'Jack' + | 'Katie' + | 'Noah' + | 'James' + | 'Rina' + | 'Ella' + | 'Mariah' + | 'Frank' + | 'Claudia' + | 'Niki' + | 'Vincent' + | 'Kendrick' + | 'Myrna' + | 'Tom' + | 'Wanda' + | 'Benjamin' + | 'Kiana' + | 'Rachel'; + + type: 'preset'; + } + + /** + * Clone a voice from a reference audio clip, then speak promptText in that voice. + * Routes only to models that support voice cloning. + */ + export interface ReferenceAudio { + /** + * A HTTPS URL. + */ + audioUri: string; + + type: 'reference-audio'; + } + } +} + +export declare namespace Audio { + export { type AudioCreateResponse as AudioCreateResponse, type AudioCreateParams as AudioCreateParams }; +} diff --git a/src/resources/generate/generate.ts b/src/resources/generate/generate.ts index 2d7d265..e4e5c21 100644 --- a/src/resources/generate/generate.ts +++ b/src/resources/generate/generate.ts @@ -1,14 +1,22 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from '../../core/resource'; +import * as AudioAPI from './audio'; +import { Audio, AudioCreateParams, AudioCreateResponse } from './audio'; +import * as ImageAPI from './image'; +import { Image, ImageCreateParams, ImageCreateResponse } from './image'; import * as VideoAPI from './video'; import { Video, VideoCreateParams, VideoCreateResponse } from './video'; export class Generate extends APIResource { video: VideoAPI.Video = new VideoAPI.Video(this._client); + image: ImageAPI.Image = new ImageAPI.Image(this._client); + audio: AudioAPI.Audio = new AudioAPI.Audio(this._client); } Generate.Video = Video; +Generate.Image = Image; +Generate.Audio = Audio; export declare namespace Generate { export { @@ -16,4 +24,16 @@ export declare namespace Generate { type VideoCreateResponse as VideoCreateResponse, type VideoCreateParams as VideoCreateParams, }; + + export { + Image as Image, + type ImageCreateResponse as ImageCreateResponse, + type ImageCreateParams as ImageCreateParams, + }; + + export { + Audio as Audio, + type AudioCreateResponse as AudioCreateResponse, + type AudioCreateParams as AudioCreateParams, + }; } diff --git a/src/resources/generate/image.ts b/src/resources/generate/image.ts new file mode 100644 index 0000000..d36593d --- /dev/null +++ b/src/resources/generate/image.ts @@ -0,0 +1,201 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../../core/resource'; +import { APIPromise } from '../../core/api-promise'; +import { RequestOptions } from '../../internal/request-options'; + +export class Image extends APIResource { + /** + * Start an image generation task using a saved Model Router config instead of + * naming a model. + */ + create(body: ImageCreateParams, options?: RequestOptions): APIPromise { + return this._client.post('/v1/generate/image', { body, ...options }); + } +} + +export interface ImageCreateResponse { + /** + * The ID of the created task. Poll GET /v1/tasks/:id for the result. + */ + id: string; + + /** + * Metadata describing which model the router selected and why. + */ + routing: ImageCreateResponse.Routing; +} + +export namespace ImageCreateResponse { + /** + * Metadata describing which model the router selected and why. + */ + export interface Routing { + /** + * The slug of the router config that was applied to this request. + */ + configId: string; + + /** + * Estimated cost, computed against current pricing. + */ + estimatedCost: Routing.EstimatedCost; + + /** + * The public name of the model the router selected. + */ + model: string; + + /** + * The provider of the selected model. + */ + provider: string; + + /** + * Request-side defaults resolved for the routing response. Not necessarily + * identical to prepared model options. + */ + resolvedInput: Routing.ResolvedInput; + + /** + * The resolved config settings the router used for this request. + */ + resolvedSettings: Routing.ResolvedSettings; + } + + export namespace Routing { + /** + * Estimated cost, computed against current pricing. + */ + export interface EstimatedCost { + /** + * Estimated cost of the generation in credits. + */ + credits: number; + } + + /** + * Request-side defaults resolved for the routing response. Not necessarily + * identical to prepared model options. + */ + export interface ResolvedInput { + /** + * Aspect ratio used for routing display. + */ + aspectRatio: string; + + /** + * Concrete output ratio derived from aspectRatio and resolution for the selected + * model. + */ + ratio: string; + + /** + * Megapixel tier used for routing display. + */ + resolution: string; + } + + /** + * The resolved config settings the router used for this request. + */ + export interface ResolvedSettings { + /** + * The single optimization preference the config selected, used as the soft + * weighting when scoring eligible models. + */ + optimizeFor: 'cost' | 'latency' | 'quality'; + + /** + * The applied maximum credits per generation for this request’s modality, or null + * if the config sets no ceiling. + */ + priceCeiling: number | null; + } + } +} + +export interface ImageCreateParams { + /** + * The slug of a saved Model Router config to route this request with. + */ + configId: string; + + /** + * Model-agnostic image generation input. The router selects a model and maps these + * options to it. + */ + input: ImageCreateParams.Input; +} + +export namespace ImageCreateParams { + /** + * Model-agnostic image generation input. The router selects a model and maps these + * options to it. + */ + export interface Input { + /** + * A text prompt describing the desired image. + */ + promptText: string; + + /** + * Desired aspect ratio. Models that do not support the requested aspect are + * excluded. + */ + aspectRatio?: '16:9' | '9:16' | '1:1' | '4:3' | '3:4' | '21:9' | '2:3' | '3:2' | '4:5' | '5:4'; + + /** + * Settings that affect the behavior of the content moderation system. + */ + contentModeration?: Input.ContentModeration; + + /** + * Number of images to generate (1–10). Models that cannot produce the exact count + * are excluded and cost scales with this value. + */ + outputCount?: number; + + /** + * Optional reference images for models that support them. Tags are assigned per + * model when omitted. + */ + referenceImages?: Array; + + /** + * Desired megapixel tier. Models that do not support the requested tier are + * excluded. + */ + resolution?: '1k' | '2k' | '4k'; + + /** + * A seed for reproducible generation. Only gen4_image and gen4_image_turbo accept + * this field. + */ + seed?: number; + } + + export namespace Input { + /** + * Settings that affect the behavior of the content moderation system. + */ + export interface ContentModeration { + /** + * When set to `low`, the content moderation system will be less strict about + * preventing generations that include recognizable public figures. + */ + publicFigureThreshold?: 'auto' | 'low'; + } + + export interface ReferenceImage { + /** + * A HTTPS URL. + */ + uri: string; + } + } +} + +export declare namespace Image { + export { type ImageCreateResponse as ImageCreateResponse, type ImageCreateParams as ImageCreateParams }; +} diff --git a/src/resources/generate/index.ts b/src/resources/generate/index.ts index 379bec1..012c6cf 100644 --- a/src/resources/generate/index.ts +++ b/src/resources/generate/index.ts @@ -1,4 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +export { Audio, type AudioCreateResponse, type AudioCreateParams } from './audio'; export { Generate } from './generate'; +export { Image, type ImageCreateResponse, type ImageCreateParams } from './image'; export { Video, type VideoCreateResponse, type VideoCreateParams } from './video'; diff --git a/tests/api-resources/generate/audio.test.ts b/tests/api-resources/generate/audio.test.ts new file mode 100644 index 0000000..aca2533 --- /dev/null +++ b/tests/api-resources/generate/audio.test.ts @@ -0,0 +1,38 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import RunwayML from '@runwayml/sdk'; + +const client = new RunwayML({ + apiKey: 'My API Key', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource audio', () => { + test('create: only required params', async () => { + const responsePromise = client.generate.audio.create({ + configId: 'n6_', + input: { promptText: 'x', type: 'speech' }, + }); + 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.generate.audio.create({ + configId: 'n6_', + input: { + promptText: 'x', + type: 'speech', + duration: 0.5, + loop: true, + referenceAudios: [{ uri: 'https://example.com/file' }], + voice: { presetId: 'Maya', type: 'preset' }, + }, + }); + }); +}); diff --git a/tests/api-resources/generate/image.test.ts b/tests/api-resources/generate/image.test.ts new file mode 100644 index 0000000..3bd5577 --- /dev/null +++ b/tests/api-resources/generate/image.test.ts @@ -0,0 +1,39 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import RunwayML from '@runwayml/sdk'; + +const client = new RunwayML({ + apiKey: 'My API Key', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource image', () => { + test('create: only required params', async () => { + const responsePromise = client.generate.image.create({ + configId: 'n6_', + input: { promptText: 'x' }, + }); + 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.generate.image.create({ + configId: 'n6_', + input: { + promptText: 'x', + aspectRatio: '16:9', + contentModeration: { publicFigureThreshold: 'auto' }, + outputCount: 1, + referenceImages: [{ uri: 'https://example.com/file' }], + resolution: '1k', + seed: 0, + }, + }); + }); +}); From 331945fe026d13ea866d8888c00ec5195a3408c7 Mon Sep 17 00:00:00 2001 From: Robin Andeer Date: Thu, 23 Jul 2026 17:12:08 -0400 Subject: [PATCH 3/4] fix(client): make generate.image and generate.audio responses awaitable --- src/resources/generate/audio.ts | 11 ++++++++--- src/resources/generate/image.ts | 11 ++++++++--- tests/api-resources/generate/audio.test.ts | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/resources/generate/audio.ts b/src/resources/generate/audio.ts index 57fdbff..50da9ab 100644 --- a/src/resources/generate/audio.ts +++ b/src/resources/generate/audio.ts @@ -1,8 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from '../../core/resource'; -import { APIPromise } from '../../core/api-promise'; import { RequestOptions } from '../../internal/request-options'; +import { APIPromiseWithAwaitableTask, wrapAsWaitableResource } from '../../lib/polling'; export class Audio extends APIResource { /** @@ -10,8 +10,13 @@ export class Audio extends APIResource { * naming a model. Set input.type to speech to speak promptText verbatim, or audio * to generate audio described by promptText. */ - create(body: AudioCreateParams, options?: RequestOptions): APIPromise { - return this._client.post('/v1/generate/audio', { body, ...options }); + create( + body: AudioCreateParams, + options?: RequestOptions, + ): APIPromiseWithAwaitableTask { + return wrapAsWaitableResource(this._client)( + this._client.post('/v1/generate/audio', { body, ...options }), + ); } } diff --git a/src/resources/generate/image.ts b/src/resources/generate/image.ts index d36593d..627b1ef 100644 --- a/src/resources/generate/image.ts +++ b/src/resources/generate/image.ts @@ -1,16 +1,21 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from '../../core/resource'; -import { APIPromise } from '../../core/api-promise'; import { RequestOptions } from '../../internal/request-options'; +import { APIPromiseWithAwaitableTask, wrapAsWaitableResource } from '../../lib/polling'; export class Image extends APIResource { /** * Start an image generation task using a saved Model Router config instead of * naming a model. */ - create(body: ImageCreateParams, options?: RequestOptions): APIPromise { - return this._client.post('/v1/generate/image', { body, ...options }); + create( + body: ImageCreateParams, + options?: RequestOptions, + ): APIPromiseWithAwaitableTask { + return wrapAsWaitableResource(this._client)( + this._client.post('/v1/generate/image', { body, ...options }), + ); } } diff --git a/tests/api-resources/generate/audio.test.ts b/tests/api-resources/generate/audio.test.ts index aca2533..44d24cd 100644 --- a/tests/api-resources/generate/audio.test.ts +++ b/tests/api-resources/generate/audio.test.ts @@ -30,7 +30,7 @@ describe('resource audio', () => { type: 'speech', duration: 0.5, loop: true, - referenceAudios: [{ uri: 'https://example.com/file' }], + // referenceAudios omitted — Input.ReferenceAudio is overloaded with voice clone shape in codegen voice: { presetId: 'Maya', type: 'preset' }, }, }); From 916929d69af0dadaddb0f002168292b9056d2c23 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 23 Jul 2026 21:12:25 +0000 Subject: [PATCH 4/4] release: 4.12.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 14 ++++++++++++++ package.json | 2 +- src/version.ts | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 58acdf5..8167506 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.11.0" + ".": "4.12.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 46a8f46..4d33e1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 4.12.0 (2026-07-23) + +Full Changelog: [v4.11.0...v4.12.0](https://github.com/runwayml/sdk-node/compare/v4.11.0...v4.12.0) + +### Features + +* **api:** add Model Router image and audio generation ([fcf6b45](https://github.com/runwayml/sdk-node/commit/fcf6b458f5dac025834a26b68098e175d0677916)) +* **api:** expose generate image and audio endpoints ([babe552](https://github.com/runwayml/sdk-node/commit/babe5528cccd693ec6e30f94db59ffa5b3e708c0)) + + +### Bug Fixes + +* **client:** make generate.image and generate.audio responses awaitable ([331945f](https://github.com/runwayml/sdk-node/commit/331945fe026d13ea866d8888c00ec5195a3408c7)) + ## 4.11.0 (2026-07-21) Full Changelog: [v4.10.0...v4.11.0](https://github.com/runwayml/sdk-node/compare/v4.10.0...v4.11.0) diff --git a/package.json b/package.json index 24a8970..5ed20d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@runwayml/sdk", - "version": "4.11.0", + "version": "4.12.0", "description": "The official TypeScript library for the RunwayML API", "author": "RunwayML ", "types": "dist/index.d.ts", diff --git a/src/version.ts b/src/version.ts index ac2d33f..c8d4c56 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '4.11.0'; // x-release-please-version +export const VERSION = '4.12.0'; // x-release-please-version