Skip to content

Commit 7357d10

Browse files
feat(api): Add Video APIs
1 parent 928493c commit 7357d10

File tree

7 files changed

+306
-5
lines changed

7 files changed

+306
-5
lines changed

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 39
1+
configured_endpoints: 41
22
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/togetherai%2Ftogetherai-dc94b2b06f27f9d2031307115c3aa9db86a430741037ffd6baaf12304c747f02.yml
33
openapi_spec_hash: 4ad476ccff245fe0460d730bc6e44d60
4-
config_hash: e2d1be538fd1fb65bfc566a2a168cc16
4+
config_hash: 5c3a2f90c5f665091f9de844810eb099

MIGRATION.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,16 @@ If you were relying on anything that was only exported from `together-ai/core` a
133133

134134
#### Resource classes
135135

136-
Previously under certain circumstances it was possible to import resource classes like `Chat` directly from the root of the package. This was never valid at the type level and only worked in CommonJS files.
136+
Previously under certain circumstances it was possible to import resource classes like `Videos` directly from the root of the package. This was never valid at the type level and only worked in CommonJS files.
137137
Now you must always either reference them as static class properties or import them directly from the files in which they are defined.
138138

139139
```typescript
140140
// Before
141-
const { Chat } = require('together-ai');
141+
const { Videos } = require('together-ai');
142142

143143
// After
144144
const { Together } = require('together-ai');
145-
Together.Chat; // or import directly from together-ai/resources/chat/chat
145+
Together.Videos; // or import directly from together-ai/resources/videos
146146
```
147147

148148
#### Cleaned up `uploads` exports

api.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@ Methods:
88

99
- <code title="post /rerank">client.<a href="./src/index.ts">rerank</a>({ ...params }) -> RerankResponse</code>
1010

11+
# Videos
12+
13+
Types:
14+
15+
- <code><a href="./src/resources/videos.ts">VideoCreateResponse</a></code>
16+
- <code><a href="./src/resources/videos.ts">VideoRetrieveResponse</a></code>
17+
18+
Methods:
19+
20+
- <code title="post /videos">client.videos.<a href="./src/resources/videos.ts">create</a>({ ...params }) -> VideoCreateResponse</code>
21+
- <code title="get /videos/{id}">client.videos.<a href="./src/resources/videos.ts">retrieve</a>(id) -> VideoRetrieveResponse</code>
22+
1123
# Chat
1224

1325
## Completions

src/client.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ import { Hardware, HardwareListParams, HardwareListResponse } from './resources/
9696
import { ImageCreateParams, ImageDataB64, ImageDataURL, ImageFile, Images } from './resources/images';
9797
import { JobListResponse, JobRetrieveResponse, Jobs } from './resources/jobs';
9898
import { ModelListResponse, ModelUploadParams, ModelUploadResponse, Models } from './resources/models';
99+
import { VideoCreateParams, VideoCreateResponse, VideoRetrieveResponse, Videos } from './resources/videos';
99100
import {
100101
Audio,
101102
AudioCreateParams,
@@ -828,6 +829,7 @@ export class Together {
828829

829830
static toFile = Uploads.toFile;
830831

832+
videos: API.Videos = new API.Videos(this);
831833
chat: API.Chat = new API.Chat(this);
832834
completions: API.Completions = new API.Completions(this);
833835
embeddings: API.Embeddings = new API.Embeddings(this);
@@ -845,6 +847,7 @@ export class Together {
845847
evaluations: API.Evaluations = new API.Evaluations(this);
846848
}
847849

850+
Together.Videos = Videos;
848851
Together.Chat = Chat;
849852
Together.Completions = Completions;
850853
Together.Embeddings = Embeddings;
@@ -866,6 +869,13 @@ export declare namespace Together {
866869

867870
export { type RerankResponse as RerankResponse, type RerankParams as RerankParams };
868871

872+
export {
873+
Videos as Videos,
874+
type VideoCreateResponse as VideoCreateResponse,
875+
type VideoRetrieveResponse as VideoRetrieveResponse,
876+
type VideoCreateParams as VideoCreateParams,
877+
};
878+
869879
export { Chat as Chat };
870880

871881
export {

src/resources/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,10 @@ export {
9898
} from './images';
9999
export { Jobs, type JobRetrieveResponse, type JobListResponse } from './jobs';
100100
export { Models, type ModelListResponse, type ModelUploadResponse, type ModelUploadParams } from './models';
101+
export {
102+
Videos,
103+
type VideoCreateResponse,
104+
type VideoRetrieveResponse,
105+
type VideoCreateParams,
106+
} from './videos';
101107
export { type RerankResponse, type RerankParams } from './top-level';

src/resources/videos.ts

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
import { APIResource } from '../core/resource';
4+
import { APIPromise } from '../core/api-promise';
5+
import { RequestOptions } from '../internal/request-options';
6+
import { path } from '../internal/utils/path';
7+
8+
export class Videos extends APIResource {
9+
/**
10+
* Create a video
11+
*
12+
* @example
13+
* ```ts
14+
* const video = await client.videos.create({
15+
* model: 'model',
16+
* });
17+
* ```
18+
*/
19+
create(body: VideoCreateParams, options?: RequestOptions): APIPromise<VideoCreateResponse> {
20+
return this._client.post('/videos', { body, defaultBaseURL: 'https://api.together.xyz/v2', ...options });
21+
}
22+
23+
/**
24+
* Fetch video metadata
25+
*
26+
* @example
27+
* ```ts
28+
* const video = await client.videos.retrieve('id');
29+
* ```
30+
*/
31+
retrieve(id: string, options?: RequestOptions): APIPromise<VideoRetrieveResponse> {
32+
return this._client.get(path`/videos/${id}`, {
33+
defaultBaseURL: 'https://api.together.xyz/v2',
34+
...options,
35+
});
36+
}
37+
}
38+
39+
export interface VideoCreateResponse {
40+
/**
41+
* Unique identifier for the video job.
42+
*/
43+
id?: string;
44+
}
45+
46+
/**
47+
* Structured information describing a generated video job.
48+
*/
49+
export interface VideoRetrieveResponse {
50+
/**
51+
* Unique identifier for the video job.
52+
*/
53+
id: string;
54+
55+
/**
56+
* Unix timestamp (seconds) for when the job was created.
57+
*/
58+
created_at: number;
59+
60+
/**
61+
* The video generation model that produced the job.
62+
*/
63+
model: string;
64+
65+
/**
66+
* Duration of the generated clip in seconds.
67+
*/
68+
seconds: string;
69+
70+
/**
71+
* The resolution of the generated video.
72+
*/
73+
size: string;
74+
75+
/**
76+
* Current lifecycle status of the video job.
77+
*/
78+
status: 'in_progress' | 'completed' | 'failed';
79+
80+
/**
81+
* Unix timestamp (seconds) for when the job completed, if finished.
82+
*/
83+
completed_at?: number;
84+
85+
/**
86+
* Error payload that explains why generation failed, if applicable.
87+
*/
88+
error?: VideoRetrieveResponse.Error;
89+
90+
/**
91+
* The object type, which is always video.
92+
*/
93+
object?: 'video';
94+
95+
/**
96+
* Available upon completion, the outputs provides the cost charged and the hosted
97+
* url to access the video
98+
*/
99+
outputs?: VideoRetrieveResponse.Outputs;
100+
}
101+
102+
export namespace VideoRetrieveResponse {
103+
/**
104+
* Error payload that explains why generation failed, if applicable.
105+
*/
106+
export interface Error {
107+
message: string;
108+
109+
code?: string;
110+
}
111+
112+
/**
113+
* Available upon completion, the outputs provides the cost charged and the hosted
114+
* url to access the video
115+
*/
116+
export interface Outputs {
117+
/**
118+
* The cost of generated video charged to the owners account.
119+
*/
120+
cost: number;
121+
122+
/**
123+
* URL hosting the generated video
124+
*/
125+
video_url: string;
126+
}
127+
}
128+
129+
export interface VideoCreateParams {
130+
/**
131+
* The model to be used for the video creation request.
132+
*/
133+
model: string;
134+
135+
/**
136+
* Frames per second. Defaults to 24.
137+
*/
138+
fps?: number;
139+
140+
/**
141+
* Array of images to guide video generation, like keyframes. If size 1, starting
142+
* frame, if size 2, starting and ending frame, if more than 2 then frame must be
143+
* specified
144+
*/
145+
frame_images?: Array<VideoCreateParams.FrameImage>;
146+
147+
/**
148+
* Controls how closely the video generation follows your prompt. Higher values
149+
* make the model adhere more strictly to your text description, while lower values
150+
* allow more creative freedom. guidence_scale affects both visual content and
151+
* temporal consistency.Recommended range is 6.0-10.0 for most video models. Values
152+
* above 12 may cause over-guidance artifacts or unnatural motion patterns.
153+
*/
154+
guidance_scale?: number;
155+
156+
height?: number;
157+
158+
/**
159+
* Similar to prompt, but specifies what to avoid instead of what to include
160+
*/
161+
negative_prompt?: string;
162+
163+
/**
164+
* Specifies the format of the output video. Defaults to MP4.
165+
*/
166+
output_format?: 'MP4' | 'WEBM';
167+
168+
/**
169+
* Compression quality. Defaults to 20.
170+
*/
171+
output_quality?: number;
172+
173+
/**
174+
* Text prompt that describes the video to generate.
175+
*/
176+
prompt?: string;
177+
178+
/**
179+
* TODO need to figure this out
180+
*/
181+
reference_images?: Array<unknown>;
182+
183+
/**
184+
* Clip duration in seconds.
185+
*/
186+
seconds?: string;
187+
188+
/**
189+
* Seed to use in initializing the video generation. Using the same seed allows
190+
* deterministic video generation. If not provided a random seed is generated for
191+
* each request.
192+
*/
193+
seed?: number;
194+
195+
/**
196+
* The number of denoising steps the model performs during video generation. More
197+
* steps typically result in higher quality output but require longer processing
198+
* time.
199+
*/
200+
steps?: number;
201+
202+
width?: number;
203+
}
204+
205+
export namespace VideoCreateParams {
206+
export interface FrameImage {
207+
frame: number | 'first' | 'last';
208+
209+
/**
210+
* idk
211+
*/
212+
input_image: string;
213+
}
214+
}
215+
216+
export declare namespace Videos {
217+
export {
218+
type VideoCreateResponse as VideoCreateResponse,
219+
type VideoRetrieveResponse as VideoRetrieveResponse,
220+
type VideoCreateParams as VideoCreateParams,
221+
};
222+
}

tests/api-resources/videos.test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
import Together from 'together-ai';
4+
5+
const client = new Together({
6+
apiKey: 'My API Key',
7+
baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
8+
});
9+
10+
describe('resource videos', () => {
11+
test('create: only required params', async () => {
12+
const responsePromise = client.videos.create({ model: 'model' });
13+
const rawResponse = await responsePromise.asResponse();
14+
expect(rawResponse).toBeInstanceOf(Response);
15+
const response = await responsePromise;
16+
expect(response).not.toBeInstanceOf(Response);
17+
const dataAndResponse = await responsePromise.withResponse();
18+
expect(dataAndResponse.data).toBe(response);
19+
expect(dataAndResponse.response).toBe(rawResponse);
20+
});
21+
22+
test('create: required and optional params', async () => {
23+
const response = await client.videos.create({
24+
model: 'model',
25+
fps: 0,
26+
frame_images: [{ frame: 0, input_image: 'input_image' }],
27+
guidance_scale: 0,
28+
height: 0,
29+
negative_prompt: 'negative_prompt',
30+
output_format: 'MP4',
31+
output_quality: 0,
32+
prompt: 'x',
33+
reference_images: [{}],
34+
seconds: 'seconds',
35+
seed: 0,
36+
steps: 10,
37+
width: 0,
38+
});
39+
});
40+
41+
test('retrieve', async () => {
42+
const responsePromise = client.videos.retrieve('id');
43+
const rawResponse = await responsePromise.asResponse();
44+
expect(rawResponse).toBeInstanceOf(Response);
45+
const response = await responsePromise;
46+
expect(response).not.toBeInstanceOf(Response);
47+
const dataAndResponse = await responsePromise.withResponse();
48+
expect(dataAndResponse.data).toBe(response);
49+
expect(dataAndResponse.response).toBe(rawResponse);
50+
});
51+
});

0 commit comments

Comments
 (0)