gpt-video 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GPT-Video
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,272 @@
1
- # Temporary Holding Version
1
+ # gpt-video
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The official JavaScript and TypeScript SDK for the GPT-Video API.
4
+
5
+ GPT-Video turns a long video into short vertical clips with captions and face framing. Your program uploads a video, GPT-Video finds the moments that work as clips, and your program exports the ones it keeps as MP4 files.
6
+
7
+ - One method for each of the 67 operations of the API, named after the [API reference](https://www.gpt-video.com/developers/api): `analyze_project` is `analyzeProject`.
8
+ - Retries that never pay twice: a call that spends sends the same Idempotency-Key on every attempt.
9
+ - Helpers for the work that takes more than one request: `uploadFile`, `wait`, `paginate`, `download`, and webhook verification.
10
+ - No dependencies. ES modules for Node.js 20.19 or later, Deno, Bun and Cloudflare Workers. TypeScript types come with the package.
11
+
12
+ ## Install
13
+
14
+ ```sh
15
+ npm install gpt-video
16
+ ```
17
+
18
+ ## Your first clip
19
+
20
+ 1. Create a GPT-Video account and confirm your email address.
21
+ 2. Open the Developers page of the app, https://www.gpt-video.com/app/developers, and create an API key with the scopes `clips:read`, `clips:write` and `spend`. The key is shown once, so copy it then.
22
+ 3. Put the key in the environment, where the SDK reads it, and run the quickstart on a video of yours:
23
+
24
+ ```sh
25
+ export GPT_VIDEO_API_KEY=gvk_...
26
+ node quickstart.mjs talk.mp4
27
+ ```
28
+
29
+ The program below is `examples/quickstart.mjs`. It checks the key, uploads the video, shows the price, analyzes the video, accepts the first clip, exports it and saves it as `clip.mp4`. Our test suite runs this file, unchanged, against a test server of the API.
30
+
31
+ ```js
32
+ // GPT-Video quickstart: from a video file to a vertical clip on your disk.
33
+ //
34
+ // npm install gpt-video
35
+ // export GPT_VIDEO_API_KEY=gvk_...
36
+ // node quickstart.mjs talk.mp4
37
+ //
38
+ // Steps 1 to 4 use no credits. Step 5 spends credits: one per started minute of the video.
39
+ // Step 7 uses one export of your daily allowance, and one API bonus credit while the bonus pays.
40
+
41
+ import { openAsBlob } from "node:fs";
42
+ import { writeFile } from "node:fs/promises";
43
+ import { basename } from "node:path";
44
+ import { GptVideo, GptVideoError } from "gpt-video";
45
+
46
+ const path = process.argv[2];
47
+ if (!path) {
48
+ console.error("Usage: node quickstart.mjs <video file>");
49
+ process.exit(2);
50
+ }
51
+
52
+ const gv = new GptVideo(); // reads GPT_VIDEO_API_KEY
53
+
54
+ // A call that spends and ends without a clear answer (the network failed, or the time ran out) may have
55
+ // been charged. Calling again with the same idempotencyKey returns the first answer and never pays twice.
56
+ async function spendOnce(call) {
57
+ try {
58
+ return await call({});
59
+ } catch (error) {
60
+ if (!(error instanceof GptVideoError) || !error.mayHaveSpent) throw error;
61
+ console.log(`No clear answer (${error.code}). Asking again with the same Idempotency-Key.`);
62
+ return call({ idempotencyKey: error.idempotencyKey });
63
+ }
64
+ }
65
+
66
+ // 1. Check the key.
67
+ const me = await gv.getMe();
68
+ console.log(`Key ${me.key.id} works. Scopes: ${me.key.scopes.join(", ")}. Plan: ${me.account.plan}.`);
69
+
70
+ // 2. Upload the video. The SDK sends it in parts and reads one part at a time from the disk.
71
+ const { asset } = await gv.uploadFile(await openAsBlob(path), {
72
+ filename: basename(path),
73
+ onProgress: ({ uploadedBytes, totalBytes }) => console.log(`Uploaded ${Math.round((100 * uploadedBytes) / totalBytes)}%`),
74
+ });
75
+ console.log(`Video ${asset.id} is ready.`);
76
+
77
+ // 3. Create an Auto Clip project. Auto Clip has no default settings: the analysis starts only when
78
+ // missingSettings is empty, so choose every one of them.
79
+ const { project } = await gv.createProject({
80
+ sourceAssetId: asset.id,
81
+ title: basename(path),
82
+ settings: {
83
+ language: "auto",
84
+ clipCount: 3,
85
+ minDurationSec: 15,
86
+ maxDurationSec: 60,
87
+ objective: "viral",
88
+ captionStyle: "word-pop",
89
+ reframe: "face",
90
+ },
91
+ });
92
+ if (project.missingSettings.length > 0) throw new Error(`Settings still to choose: ${project.missingSettings.join(", ")}`);
93
+
94
+ // 4. Ask the price of the analysis.
95
+ const { estimate } = await gv.estimateAnalysis({ projectId: project.id });
96
+ console.log(`The analysis costs ${estimate.creditsToCharge} credits.`);
97
+ if (!estimate.enough) {
98
+ console.error("The account cannot pay for it. See https://www.gpt-video.com/developers/pricing");
99
+ process.exit(1);
100
+ }
101
+
102
+ // 5. Analyze the video, and wait until its clips are found.
103
+ const analysis = await spendOnce((options) => gv.analyzeProject({ projectId: project.id }, options));
104
+ console.log(`Analysis started (${analysis.creditsCharged} credits charged). Waiting for job ${analysis.job.id}.`);
105
+ await gv.wait(analysis);
106
+
107
+ // 6. Read the clips in the order the analysis ranked them, and accept the first one. Accepting makes a
108
+ // composition, whose framing follows the face of the speaker; it can be exported once its framing job is done.
109
+ const clips = [];
110
+ for await (const clip of gv.paginate("listClips", { projectId: project.id, status: "proposed" })) clips.push(clip);
111
+ for (const clip of clips) console.log(`${clip.rank + 1}. ${clip.title} (${clip.startSec}s to ${clip.endSec}s, score ${clip.score})`);
112
+ if (clips.length === 0) throw new Error("The analysis found no clips in this video.");
113
+ const { composition } = await gv.acceptClip({ clipId: clips[0].id });
114
+ if (composition.framing.jobId) await gv.waitForJob(composition.framing.jobId);
115
+
116
+ // 7. Export the composition to an MP4 file, wait for it, and download it. The download link is its own
117
+ // credential: the SDK never sends your API key to it.
118
+ const exported = await spendOnce((options) => gv.createExport({ compositionId: composition.id }, options));
119
+ const done = await gv.wait(exported);
120
+ const response = await gv.download(done.downloadUrl);
121
+ await writeFile("clip.mp4", response.body);
122
+ console.log(`Saved clip.mp4 (${done.file.sizeBytes} bytes).`);
123
+ ```
124
+
125
+ ## What uses credits
126
+
127
+ - `getMe`, `uploadFile`, `createProject`, `estimateAnalysis`, `listClips`, `acceptClip` and every other read use no credits. An upload counts toward the storage of the account.
128
+ - `analyzeProject` charges one credit per started minute of the source video when the analysis starts. The credits are not returned if the analysis fails, and analyzing again is charged again.
129
+ - `createExport` uses one export of the daily allowance, which starts again at 00:00 UTC. While the API bonus pays, it also uses one bonus credit.
130
+
131
+ Every method links to its page of the API reference, which says what it costs. [API pricing](https://www.gpt-video.com/developers/pricing) has the API bonus, the plans and the daily limits.
132
+
133
+ ## When a call fails
134
+
135
+ Every error the SDK throws is a `GptVideoError`, with these fields:
136
+
137
+ | Field | What it says |
138
+ |---|---|
139
+ | `code` | The code of the API, such as `NOT_READY`, or one of the SDK's: `CONNECTION_FAILED`, `TIMEOUT`, `ABORTED`, `BAD_RESPONSE`, `INVALID_ARGUMENT`, `JOB_FAILED`, `JOB_CANCELLED`, `WAIT_TIMEOUT`, `WEBHOOK_VERIFICATION_FAILED` |
140
+ | `retryable` | Whether the same call, sent again with the same `idempotencyKey`, can succeed |
141
+ | `operation` | The operation of the call, such as `analyze_project` |
142
+ | `idempotencyKey` | The Idempotency-Key the call sent, or null for a call that sends none |
143
+ | `mayHaveSpent` | true when a call that spends ended without a clear answer |
144
+
145
+ `GptVideoApiError` is an error the API answered, with `status`, `requestId`, `hint`, `details` and `retryAfterSec`. `GptVideoNetworkError` is a request that got no usable answer. `GptVideoJobError` is work that `wait` was following and that failed, was cancelled or ran past the time of the wait: `handle` is the job, the export, the tool run or the turn as the last read gave it, and `errorMessage` says why the work failed. The `message` of an error has the form `NOT_READY (409): message of the API Hint: what to do [request req_...]`. The API key never appears in an error.
146
+
147
+ ### Retries
148
+
149
+ The SDK sends a call again after a failure only when that is safe: a read, a PATCH, PUT or DELETE, which has the same effect when sent twice, or a POST that carries an Idempotency-Key. It retries `CONNECTION_FAILED`, `TIMEOUT`, `NOT_READY`, `INTERNAL`, `UPSTREAM_FAILED`, `UNAVAILABLE` (unless the API is switched off) and a `BAD_RESPONSE` with a 5xx status, up to `maxRetries` times (2). It waits the seconds of `Retry-After` when the API sends it, and otherwise a growing pause with jitter. A `Retry-After` longer than 60 seconds, or longer than the time the call has left, ends the call, and the error carries it in `retryAfterSec`. `RATE_LIMITED` is retried for every call, because the API refuses it before running anything. `onRetry` is told before every pause.
150
+
151
+ `IDEMPOTENCY_IN_PROGRESS` means the first request with the same key is still running on the server. The SDK waits and asks again with the same key until it gets the answer, and this does not count toward `maxRetries`.
152
+
153
+ `timeoutMs` (60 seconds) is the time of one attempt, and `deadlineMs` (180 seconds) the time of the whole call, pauses included.
154
+
155
+ ### A call that may have spent
156
+
157
+ A call that spends gets an Idempotency-Key made once for the call, before the first attempt, and sent again on every retry. For 24 hours the API answers a key whose request succeeded with that same answer, marked replayed, and does not run the call again. A key whose request ended in an error can be sent again: the request runs again, and a charge it already made is not made a second time.
158
+
159
+ When a call that spends ends without a clear answer after its retries, its error has `mayHaveSpent: true`: the API may have charged it. Call again with `{ idempotencyKey: error.idempotencyKey }` as the second argument. If the first request ran, you get its answer and pay nothing more; if it did not, it runs now. The `spendOnce` function of the quickstart does this. A new key would be a new request, charged again.
160
+
161
+ Every POST that writes or spends sends a key, and you can pass one of your own in its second argument: 1 to 255 visible ASCII characters, with no spaces. A PATCH, PUT or DELETE takes none.
162
+
163
+ ### CONFLICT
164
+
165
+ A `CONFLICT` is never retried. When it says that the revision you sent is no longer the current one, read the composition or the timeline again and decide from what it holds now. A change you sent as a new call, after an earlier call of the same change ended in an error, may already be in it: to send a change again, pass the `idempotencyKey` of that error, and if the first one was written you get its answer.
166
+
167
+ ### NOT_READY after acceptClip
168
+
169
+ When the project follows the face of the speaker, `acceptClip` starts a framing job on the new composition, and `composition.framing.jobId` is that job. Until it is done, `createExport` answers `NOT_READY`; the SDK waits the seconds of `Retry-After` and sends it again with the same key, up to `maxRetries` times. The quickstart waits for the framing job with `waitForJob` first, so the export starts at once.
170
+
171
+ ## Waiting for work
172
+
173
+ `analyzeProject`, `createExport`, the tools and the Editor Assistant start work and answer at once with the job, the export, the tool run or the turn. `gv.wait(answer)` takes that answer and reads the work again until it is done, failed or cancelled. Each read waits on the server for up to 25 seconds, so a wait sends few requests.
174
+
175
+ - `timeoutMs` is 60 minutes. A longer wait throws `WAIT_TIMEOUT`, with the last object read. Ending a wait never stops the work: waiting again picks it up.
176
+ - Work that failed or was cancelled throws `GptVideoJobError`. With `throwOnFailure: false` the wait returns the object instead.
177
+ - `onProgress` is told of every read.
178
+ - `waitForJob`, `waitForExport`, `waitForToolRun` and `waitForAssistantTurn` take an id or an object.
179
+
180
+ ## Lists
181
+
182
+ The nine list methods answer one page at a time. `gv.paginate` follows `nextCursor` for you, and asks for a page only when the items before it are used up:
183
+
184
+ - `gv.paginate("listProjects", { limit: 100 })` goes through every project.
185
+ - `gv.paginate("listClips", { projectId, status: "proposed" })` goes through the clips of a project, in the order the analysis ranked them.
186
+
187
+ ## Uploads and downloads
188
+
189
+ `uploadFile` takes a `Blob` or a `File`, an `ArrayBuffer`, a typed array, or a `ReadableStream` with `sizeBytes`. In Node.js, open a file on disk with `openAsBlob` from `node:fs`: the SDK reads one part at a time and never holds the whole file in memory.
190
+
191
+ - The API takes MP4, MOV, MKV, WebM, AVI and MPEG-TS files up to 8 GB, and chooses the size of the parts.
192
+ - Four parts travel at once (`concurrency`, up to 16), and each part is retried on its own.
193
+ - Each part has its own timeout: 60 seconds, or longer for a part that needs it at 100 KB a second, up to 10 minutes. After a part times out, the rest go one at a time.
194
+ - If the upload fails, the SDK cancels it.
195
+ - `onProgress` is told after every part the API received.
196
+
197
+ An upload takes as long as your connection needs to send the file. 1 GB is 8,000 megabits, so on a 10 Mbit/s upload link it takes at least 800 seconds, about 13 minutes.
198
+
199
+ `download(url)` fetches a signed link, such as the `downloadUrl` of a finished export, and returns the `Response` once its headers arrive. It never sends your API key, accepts only `https` links, and retries a failure that comes before the answer, as it does for a read. A link expires after a while: read the export again with `getExport` for a new one.
200
+
201
+ ## Webhooks
202
+
203
+ GPT-Video can call your server when a job or an export ends. You add the address on the Developers page of the app, which shows the signing secret of the webhook. It starts with `whsec_`. [Webhooks](https://www.gpt-video.com/developers/webhooks) describes the events.
204
+
205
+ `gpt-video/webhooks` checks a delivery on the raw request body, before you parse it as JSON:
206
+
207
+ - `verifyWebhook({ secret, headers, body })` checks it and returns the `id` and `timestamp` of the delivery.
208
+ - `constructEvent({ secret, headers, body })` checks it and returns the event.
209
+ - `new Webhook(secret).verify(body, headers)` has the form of the Standard Webhooks libraries, so a receiver that uses one of them changes only its import.
210
+
211
+ A delivery that does not check out throws `WebhookVerificationError`, whose `reason` says why. A timestamp more than 300 seconds from your clock is refused (`toleranceSec`).
212
+
213
+ ## Options
214
+
215
+ `new GptVideo(options)` checks every option before anything is sent.
216
+
217
+ | Option | Default | What it does |
218
+ |---|---|---|
219
+ | `apiKey` | `GPT_VIDEO_API_KEY` | The API key. It starts with `gvk_`. |
220
+ | `baseUrl` | `https://api.gpt-video.com/v1` | The address of the API, with or without `/v1` |
221
+ | `maxRetries` | 2 | Failures retried after the first attempt |
222
+ | `timeoutMs` | 60000 | The time of one attempt |
223
+ | `deadlineMs` | 180000 | The time of a whole call, pauses included |
224
+ | `fetch` | the global `fetch` | The function that sends requests |
225
+ | `onResponse` | none | Told of every answer, with its status and rate limit |
226
+ | `onRetry` | none | Told before every pause, with the code and the delay |
227
+ | `userAgentSuffix` | none | Added after `gpt-video-js/<version>` in the User-Agent |
228
+ | `dangerouslyAllowBrowser` | false | Lets the SDK start in a web page |
229
+
230
+ Each call takes `idempotencyKey`, `signal`, `timeoutMs`, `deadlineMs` and `maxRetries` in its second argument.
231
+
232
+ ## In a web page
233
+
234
+ The SDK does not start in a web page: the API key would be readable by anyone who opens the page. Call the API from your server. `dangerouslyAllowBrowser: true` lets it start anyway, for a page that only you open.
235
+
236
+ ## CommonJS
237
+
238
+ The package is made of ES modules. On Node.js 20.19 or later, `require` loads it as well:
239
+
240
+ ```cjs
241
+ const { GptVideo } = require("gpt-video");
242
+
243
+ const gv = new GptVideo();
244
+ gv.getMe().then((me) => console.log(`Key ${me.key.id} works.`));
245
+ ```
246
+
247
+ ## From MCP to the SDK
248
+
249
+ If you used GPT-Video through its MCP server, most tools there have a method here that does the same work, with the same name in camelCase: `get_credits` is `getCredits`. These tools have another name here:
250
+
251
+ | MCP tool | SDK method | How they relate |
252
+ |---|---|---|
253
+ | `create_auto_clip_project` | `createProject` | The same operation |
254
+ | `configure_project` | `updateProject` | Close work with other arguments |
255
+ | `find_clips` | `analyzeProject` | Close work with other arguments |
256
+ | `export_clip` | `acceptClip` | Close work with other arguments |
257
+ | `export_clip` | `createExport` | Close work with other arguments |
258
+ | `wait_for_job` | `getJob` | The same operation |
259
+
260
+ For close work, read the page of the method before you switch.
261
+
262
+ The first tools of the MCP server were written by hand before the API, and five of them share a name with a method here but have arguments and answers of their own: `list_projects`, `create_project`, `get_project`, `list_clips` and `get_job`. On MCP, `create_project` makes an empty project for a video the user uploads in the app; `createProject` here takes the video in `sourceAssetId`. Read the page of the method for these too.
263
+
264
+ On MCP a tool that spends needs `confirm: true`. The SDK has no such field: calling the method is the decision.
265
+
266
+ ## Versions
267
+
268
+ Version 1.0.0 of the SDK calls version 1 of the API. The answers come back as the API sends them, so a field the API adds reaches your code before the SDK knows it. [CHANGELOG.md](CHANGELOG.md) lists the changes.
269
+
270
+ Questions: hello@gpt-video.com. The API documentation: https://www.gpt-video.com/developers.
271
+
272
+ MIT license.
package/package.json CHANGED
@@ -1,6 +1,56 @@
1
1
  {
2
2
  "name": "gpt-video",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "description": "The official JavaScript and TypeScript SDK for the GPT-Video API: upload a video, find clips, export them.",
5
+ "license": "MIT",
6
+ "homepage": "https://www.gpt-video.com/developers",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/gptvideo/gpt-video-sdks.git",
10
+ "directory": "js"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/gptvideo/gpt-video-sdks/issues"
14
+ },
15
+ "author": {
16
+ "name": "GPT-Video",
17
+ "email": "hello@gpt-video.com"
18
+ },
19
+ "keywords": [
20
+ "gpt-video",
21
+ "video",
22
+ "video-editing",
23
+ "clips",
24
+ "captions",
25
+ "api",
26
+ "sdk"
27
+ ],
28
+ "type": "module",
29
+ "sideEffects": false,
30
+ "exports": {
31
+ ".": "./src/index.mjs",
32
+ "./webhooks": "./src/webhooks.mjs"
33
+ },
34
+ "files": [
35
+ "src/*.mjs",
36
+ "src/*.d.ts",
37
+ "src/*.d.mts",
38
+ "!src/*.test.mjs",
39
+ "LICENSE",
40
+ "README.md"
41
+ ],
42
+ "engines": {
43
+ "node": ">=20.19"
44
+ },
45
+ "scripts": {
46
+ "typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.lib.json",
47
+ "test": "vitest run",
48
+ "prepack": "tsc -p tsconfig.dts.json",
49
+ "postpack": "node -e \"const fs = require('node:fs'); for (const f of fs.readdirSync('src')) if (f.endsWith('.d.mts')) fs.rmSync('src/' + f)\""
50
+ },
51
+ "devDependencies": {
52
+ "@types/node": "^24.0.0",
53
+ "typescript": "^5.9.0",
54
+ "vitest": "^3.2.0"
55
+ }
56
+ }
@@ -0,0 +1,160 @@
1
+ /** @import * as T from "./types.generated.js" */
2
+ /** @import { GptVideoOptions } from "./transport.mjs" */
3
+ /** @import { WaitOptions } from "./wait.mjs" */
4
+ /** @import { PaginateOptions } from "./paginate.mjs" */
5
+ /** @import { UploadOptions } from "./upload.mjs" */
6
+ /** @import { DownloadOptions } from "./download.mjs" */
7
+ /** The operation table of this version, indexed once when the package loads. */
8
+ export const OPERATION_INDEX: OperationIndex;
9
+ /**
10
+ * The API's retryable error codes, from the generated error table.
11
+ * @type {ReadonlySet<string>}
12
+ */
13
+ export const RETRYABLE_CODES: ReadonlySet<string>;
14
+ /**
15
+ * A client of the GPT-Video API.
16
+ *
17
+ * ```js
18
+ * const gv = new GptVideo(); // reads GPT_VIDEO_API_KEY
19
+ * const { asset } = await gv.uploadFile(await fs.openAsBlob("talk.mp4"), { filename: "talk.mp4" });
20
+ * ```
21
+ *
22
+ * A call that spends sends an Idempotency-Key, made once for the call and sent again on every retry, so a
23
+ * retry never pays twice. When a call that spends ends without a clear answer, its error says so in
24
+ * `mayHaveSpent` and carries the key in `idempotencyKey`: call again with that key to get the answer
25
+ * without paying twice.
26
+ */
27
+ export class GptVideo extends GptVideoOperations {
28
+ /**
29
+ * @param {GptVideoOptions} [options] Every option is checked here: a mistake throws GptVideoError with
30
+ * INVALID_ARGUMENT before anything is sent. In a web page the client does not start unless
31
+ * `dangerouslyAllowBrowser` is true.
32
+ */
33
+ constructor(options?: GptVideoOptions);
34
+ /**
35
+ * Waits for the work that a call started, and resolves to the object as the last read gave it: the job, the
36
+ * export, the tool run or the Editor Assistant turn. Pass the whole answer of the call.
37
+ *
38
+ * ```js
39
+ * const { job } = await gv.analyzeProject({ projectId });
40
+ * const done = await gv.wait({ job });
41
+ * ```
42
+ *
43
+ * Work that failed or was cancelled throws GptVideoJobError, which carries the object, unless
44
+ * `throwOnFailure` is false. A wait longer than `timeoutMs` (60 minutes) throws WAIT_TIMEOUT. Each read is a
45
+ * call with its own retries, and a read that still fails after them ends the wait with its error. Ending a
46
+ * wait never stops the work: waiting again can pick it up.
47
+ *
48
+ * @template {T.AsyncResult} R
49
+ * @param {R} result the answer of a call that starts work: `{ job }`, `{ export }`, `{ toolRun }` or `{ turn }`
50
+ * @param {WaitOptions} [options]
51
+ * @returns {Promise<T.AsyncHandles[keyof R & keyof T.AsyncHandles]>}
52
+ */
53
+ wait<R extends T.AsyncResult>(result: R, options?: WaitOptions): Promise<T.AsyncHandles[keyof R & keyof T.AsyncHandles]>;
54
+ /**
55
+ * Waits for a job until it is done, failed or cancelled. Takes the job id, the job, or the answer that carries it.
56
+ * @param {string | { id: string } | { job: { id: string } }} job
57
+ * @param {WaitOptions} [options]
58
+ * @returns {Promise<T.Job>}
59
+ */
60
+ waitForJob(job: string | {
61
+ id: string;
62
+ } | {
63
+ job: {
64
+ id: string;
65
+ };
66
+ }, options?: WaitOptions): Promise<T.Job>;
67
+ /**
68
+ * Waits for an export until it is done, failed or cancelled; the export it resolves to has its downloadUrl.
69
+ * Takes the export id, the export, or the answer that carries it.
70
+ * @param {string | { id: string } | { export: { id: string } }} exported
71
+ * @param {WaitOptions} [options]
72
+ * @returns {Promise<T.Export>}
73
+ */
74
+ waitForExport(exported: string | {
75
+ id: string;
76
+ } | {
77
+ export: {
78
+ id: string;
79
+ };
80
+ }, options?: WaitOptions): Promise<T.Export>;
81
+ /**
82
+ * Waits for a tool run until it is done or failed. Takes the run id, the run, or the answer that carries it.
83
+ * @param {string | { id: string } | { toolRun: { id: string } }} toolRun
84
+ * @param {WaitOptions} [options]
85
+ * @returns {Promise<T.ToolRun>}
86
+ */
87
+ waitForToolRun(toolRun: string | {
88
+ id: string;
89
+ } | {
90
+ toolRun: {
91
+ id: string;
92
+ };
93
+ }, options?: WaitOptions): Promise<T.ToolRun>;
94
+ /**
95
+ * Waits for an Editor Assistant turn until it is done, failed or cancelled. Takes the turn id, the turn, or
96
+ * the answer that carries it.
97
+ * @param {string | { id: string } | { turn: { id: string } }} turn
98
+ * @param {WaitOptions} [options]
99
+ * @returns {Promise<T.AssistantTurn>}
100
+ */
101
+ waitForAssistantTurn(turn: string | {
102
+ id: string;
103
+ } | {
104
+ turn: {
105
+ id: string;
106
+ };
107
+ }, options?: WaitOptions): Promise<T.AssistantTurn>;
108
+ /**
109
+ * Every item of a list, page after page, asking for each page only when the items before it are used up.
110
+ *
111
+ * ```js
112
+ * for await (const project of gv.paginate("listProjects", { limit: 100 })) console.log(project.title);
113
+ * ```
114
+ *
115
+ * @template {T.PaginatedMethod} M
116
+ * @param {M} method the name of a list method, such as listProjects
117
+ * @param {Omit<T.Operations[T.PaginatedMethods[M]]["input"], "cursor"> & { cursor?: string }} [input] the
118
+ * input of the list; a cursor is where the iteration starts
119
+ * @param {PaginateOptions} [options] for the call of every page
120
+ * @returns {AsyncGenerator<T.PageItem<M>, void, undefined>}
121
+ */
122
+ paginate<M extends T.PaginatedMethod>(method: M, input?: Omit<T.Operations[T.PaginatedMethods[M]]["input"], "cursor"> & {
123
+ cursor?: string;
124
+ }, options?: PaginateOptions): AsyncGenerator<T.PageItem<M>, void, undefined>;
125
+ /**
126
+ * Uploads a video in parts and resolves to the answer of complete_upload, `{ asset }`: pass the asset id
127
+ * to createProject as sourceAssetId. In Node.js, open a file with `fs.openAsBlob(path)`, so it is read a
128
+ * part at a time and never whole. If the upload fails, the SDK cancels it.
129
+ *
130
+ * @param {Blob | ArrayBuffer | ArrayBufferView | ReadableStream<Uint8Array>} source the file; a stream
131
+ * needs `sizeBytes`
132
+ * @param {UploadOptions} [options]
133
+ * @returns {Promise<T.CompleteUploadOutput>}
134
+ */
135
+ uploadFile(source: Blob | ArrayBuffer | ArrayBufferView | ReadableStream<Uint8Array>, options?: UploadOptions): Promise<T.CompleteUploadOutput>;
136
+ /**
137
+ * Downloads the file behind a signed link, such as the downloadUrl of an export, and resolves to the
138
+ * Response once its headers arrive. The request never carries the API key: the link is its own credential.
139
+ *
140
+ * @param {string | URL} url an https:// link
141
+ * @param {DownloadOptions} [options]
142
+ * @returns {Promise<Response>}
143
+ */
144
+ download(url: string | URL, options?: DownloadOptions): Promise<Response>;
145
+ /** How Node.js prints a client: the base URL, never the key. */
146
+ [NODE_INSPECT](): string;
147
+ /** How Deno prints a client. */
148
+ [DENO_INSPECT](): string;
149
+ #private;
150
+ }
151
+ import { OperationIndex } from "./transport.mjs";
152
+ import { GptVideoOperations } from "./client.generated.mjs";
153
+ import type * as T from "./types.generated.js";
154
+ import type { WaitOptions } from "./wait.mjs";
155
+ import type { PaginateOptions } from "./paginate.mjs";
156
+ import type { UploadOptions } from "./upload.mjs";
157
+ import type { DownloadOptions } from "./download.mjs";
158
+ import { NODE_INSPECT } from "./redact.mjs";
159
+ import { DENO_INSPECT } from "./redact.mjs";
160
+ import type { GptVideoOptions } from "./transport.mjs";