diffio 0.3.37 → 0.4.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Diffio JS SDK
2
2
 
3
- The Diffio JS SDK helps you call the Diffio API from Node. This version covers project creation, edge upload, Diffio 4.6 generations, progress checks, and download URLs.
3
+ The Diffio JS SDK helps you call the Diffio API from Node. This version covers project creation, edge upload, Diffio 4.7 generations, progress checks, and download URLs.
4
4
 
5
5
  ## Install
6
6
 
@@ -46,10 +46,11 @@ const projects = await client.listProjects({
46
46
 
47
47
  | Model | `model` value | Endpoint | Notes |
48
48
  |---|---|---|---|
49
- | Diffio 4.6 Flash | `diffio-4.6-flash` | `/v1/diffio-4.6-flash-generation` | Default. Fast, high quality speech restoration. |
50
- | Diffio 4.6 Pro | `diffio-4.6-pro` | `/v1/diffio-4.6-pro-generation` | Best quality. Paid accounts only. |
49
+ | Diffio 4.7 Flash | `diffio-4.7-flash` | `/v1/diffio-4.7-flash-generation` | Default. Fast, high quality speech restoration. |
50
+ | Diffio 4.7 Pro | `diffio-4.7-pro` | `/v1/diffio-4.7-pro-generation` | Best quality. Paid accounts only. |
51
51
 
52
- Omitting `model` uses `diffio-4.6-flash`. Earlier models (`diffio-2`, `diffio-2-flash`, `diffio-3.2`,
52
+ Omitting `model` uses `diffio-4.7-flash`. Older model names still work and run Diffio 4.7 (Flash or
53
+ Pro to match); they are deprecated. Earlier models (`diffio-2`, `diffio-2-flash`, `diffio-3.2`,
53
54
  `diffio-3.4`, `diffio-3.5`, `diffio-4.0-flash`, `diffio-4.0-pro`) are retired: the SDK refuses them
54
55
  before sending a request, and the API answers their endpoints with HTTP 410 `model_retired`.
55
56
  Generations created before a model was retired keep their original `modelKey`, so response
@@ -83,7 +84,7 @@ const project = await client.createProject({
83
84
 
84
85
  const generation = await client.createGeneration({
85
86
  apiProjectId: project.apiProjectId,
86
- model: "diffio-4.6-flash",
87
+ model: "diffio-4.7-flash",
87
88
  idempotencyKey: "restore-sample-001"
88
89
  });
89
90
 
@@ -110,7 +111,7 @@ retrying after an uncertain response.
110
111
  `waitForGeneration` and `generations.waitForComplete` wait for the overall `status` to become
111
112
  `complete`. Individual stages reaching 100% or `complete` do not end polling while video publication
112
113
  or usage settlement is still pending. They poll for up to 600 seconds unless you pass `timeout`
113
- or `timeoutInSeconds`. `complete` means restored media is ready. Diffio 4.6 transcribes the recording before
114
+ or `timeoutInSeconds`. `complete` means restored media is ready. Diffio 4.7 transcribes the recording before
114
115
  restoration starts, so a completed generation has its transcript unless transcription finished as
115
116
  `unavailable`; while a generation runs, transcription can be `pending`, `available`, or `unavailable`. Read
116
117
  `progress.transcription?.status` independently. Older responses omit `transcription`; absence does
@@ -124,7 +125,7 @@ import { DiffioClient } from "diffio";
124
125
  const client = new DiffioClient({ apiKey: "diffio_live_..." });
125
126
  const result = await client.audioIsolation.isolate({
126
127
  filePath: "sample.wav",
127
- model: "diffio-4.6-flash",
128
+ model: "diffio-4.7-flash",
128
129
  idempotencyKey: "restore-sample-001"
129
130
  });
130
131
 
@@ -145,7 +146,7 @@ import { DiffioClient } from "diffio";
145
146
  const client = new DiffioClient({ apiKey: "diffio_live_..." });
146
147
  const [audioBytes, info] = await client.restoreAudio({
147
148
  filePath: "sample.wav",
148
- model: "diffio-4.6-flash",
149
+ model: "diffio-4.7-flash",
149
150
  idempotencyKey: "restore-sample-001",
150
151
  onProgress: (progress) => console.log(progress.status)
151
152
  });
@@ -174,6 +175,14 @@ console.log(progress.status, progress.stage);
174
175
  console.log(progress.queue?.message ?? "not queued");
175
176
  console.log(progress.stageProgress?.overallPercent);
176
177
  console.log(progress.transcription?.status ?? "not reported");
178
+
179
+ for (const warning of progress.warnings) {
180
+ console.log(warning.code, warning.languages, warning.message);
181
+ }
182
+
183
+ if (progress.status === "failed" && progress.retryable) {
184
+ // A new generation for the same project can retry this failure.
185
+ }
177
186
  ```
178
187
 
179
188
  `stage` names the one step the generation is in (`pending`, `preparing`, `transcribing`, `queued`,
@@ -181,6 +190,17 @@ console.log(progress.transcription?.status ?? "not reported");
181
190
  `failed`). While it waits for a processing worker, `queue` reports its position and why it waits;
182
191
  while a worker runs it, `stageProgress` reports percentages and byte counts when known.
183
192
 
193
+ `warnings` lists things to know about the recording; the generation still runs. It is an empty array
194
+ until the transcript is ready (and when an older API version omits it). Each warning has a `code`,
195
+ `languages`, and a readable `message`. Code `unsupported_language` means the transcript has speech in
196
+ `languages` (ISO 639-1 codes such as `ja`, most words first) that Diffio does not support yet, so the
197
+ result probably won't be usable.
198
+
199
+ When `error` is present, `retryable` says whether a new generation for the same project can fix the
200
+ failure (`true` when transcription did not succeed after its automatic retries; `false`, for example,
201
+ when the upload has no speech). To retry, create a new generation for the project with a new
202
+ `idempotencyKey`, or none; reusing the failed generation's key returns that failed generation.
203
+
184
204
  ## Generation download
185
205
 
186
206
  ```ts
@@ -304,7 +324,9 @@ Use the raw request body (not parsed JSON) plus the `svix-*` headers and your we
304
324
  Verified events expose the same optional `event.transcription` object as generation progress.
305
325
  A `generation.completed` event reports `available` transcription, or `unavailable` when no
306
326
  transcript could be produced; completion does not wait for a later transcript. Older events can omit
307
- `transcription`.
327
+ `transcription`. Events include `event.warnings`, in the same shape as progress `warnings`, only when
328
+ the generation has warnings. A `generation.failed` event includes `event.retryable`, as progress
329
+ does, when the API sends it.
308
330
 
309
331
  ```ts
310
332
  import express from "express";
@@ -335,10 +357,12 @@ app.post("/webhooks/diffio", express.raw({ type: "application/json" }), (req, re
335
357
  });
336
358
  ```
337
359
 
338
- ## Upgrading to 0.3.0
360
+ ## Upgrading to 0.4.0
339
361
 
340
- 0.3.0 adds Diffio 4.6 Flash (`diffio-4.6-flash`) and Diffio 4.6 Pro (`diffio-4.6-pro`), and the
341
- default model is now `diffio-4.6-flash`. Request and response shapes are unchanged.
362
+ 0.4.0 adds Diffio 4.7 Flash (`diffio-4.7-flash`) and Diffio 4.7 Pro (`diffio-4.7-pro`), and the
363
+ default model is now `diffio-4.7-flash`. Generation progress adds `warnings` (always an array) and
364
+ `retryable`, and generation webhook events add optional `warnings` and `retryable`. If you build
365
+ `GenerationProgressResponse` objects yourself, for example as test fixtures, add `warnings: []`.
342
366
 
343
367
  ## Runtime compatibility
344
368
 
package/dist/Client.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { BaseClientOptions, BaseRequestOptions, NormalizedClientOptions } from "./BaseClient";
2
- import type { AccountSettingsResponse, ApiKeyResponse, ApiKeysListResponse, AudioIsolationResult, CompleteProjectUploadResponse, CreateGenerationResponse, CreateProjectResponse, GenerationDownloadResponse, GenerationProgressResponse, ListProjectGenerationsResponse, ListProjectsResponse, ModelKey, RestoreMetadata, UsageSummaryResponse, WebhookConfigureResponse, WebhookTestEventResponse } from "./api/types";
2
+ import type { AccountSettingsResponse, ApiKeyResponse, ApiKeysListResponse, AudioIsolationResult, CompleteProjectUploadResponse, CreateGenerationResponse, CreateProjectResponse, GenerationDownloadResponse, GenerationProgressResponse, ListProjectGenerationsResponse, ListProjectsResponse, AcceptedModelKey, RestoreMetadata, UsageSummaryResponse, WebhookConfigureResponse, WebhookTestEventResponse } from "./api/types";
3
3
  import { AccountClient, ApiKeysClient, AudioIsolationClient, GenerationsClient, ProjectsClient, UsageClient, WebhooksClient } from "./api/resources";
4
4
  export declare namespace DiffioClient {
5
5
  type Options = BaseClientOptions;
@@ -38,7 +38,7 @@ export declare class DiffioClient {
38
38
  /** Retries generation admission only when the caller supplies a nonblank idempotency key. */
39
39
  createGeneration(options: {
40
40
  apiProjectId: string;
41
- model?: ModelKey;
41
+ model?: AcceptedModelKey;
42
42
  sampling?: Record<string, unknown>;
43
43
  params?: Record<string, unknown>;
44
44
  idempotencyKey?: string;
@@ -120,7 +120,7 @@ export declare class DiffioClient {
120
120
  contentType?: string;
121
121
  contentLength?: number;
122
122
  fileFormat?: string;
123
- model?: ModelKey;
123
+ model?: AcceptedModelKey;
124
124
  sampling?: Record<string, unknown>;
125
125
  projectParams?: Record<string, unknown>;
126
126
  generationParams?: Record<string, unknown>;
@@ -142,7 +142,7 @@ export declare class DiffioClient {
142
142
  contentType?: string;
143
143
  contentLength?: number;
144
144
  fileFormat?: string;
145
- model?: ModelKey;
145
+ model?: AcceptedModelKey;
146
146
  sampling?: Record<string, unknown>;
147
147
  projectParams?: Record<string, unknown>;
148
148
  generationParams?: Record<string, unknown>;
package/dist/Client.js CHANGED
@@ -48,21 +48,23 @@ const DEFAULT_BASE_URL = "https://api.diffio.ai";
48
48
  const API_PREFIX = "v1";
49
49
  /** Generation endpoint for each supported model, as api/model_registry.json in diffio-ui lists them. */
50
50
  const MODEL_ENDPOINTS = {
51
- "diffio-4.6-flash": "diffio-4.6-flash-generation",
52
- "diffio-4.6-pro": "diffio-4.6-pro-generation"
51
+ "diffio-4.7-flash": "diffio-4.7-flash-generation",
52
+ "diffio-4.7-pro": "diffio-4.7-pro-generation"
53
53
  };
54
- /** Keys accepted from code written against 0.2.x; they run the matching 4.6 model. Not part of ModelKey. */
55
- const LEGACY_MODEL_KEYS = {
56
- "diffio-4.5-flash": "diffio-4.6-flash",
57
- "diffio-4.5-pro": "diffio-4.6-pro"
54
+ /** Deprecated aliases (the registry's `aliases`); each runs the matching 4.7 model, without a warning. */
55
+ const DEPRECATED_MODEL_KEYS = {
56
+ "diffio-4.6-flash": "diffio-4.7-flash",
57
+ "diffio-4.6-pro": "diffio-4.7-pro",
58
+ "diffio-4.5-flash": "diffio-4.7-flash",
59
+ "diffio-4.5-pro": "diffio-4.7-pro"
58
60
  };
59
61
  /** The registry's `freeDefault` model; Pro is paid-only, so it cannot be the default for every key. */
60
- const DEFAULT_MODEL_KEY = "diffio-4.6-flash";
62
+ const DEFAULT_MODEL_KEY = "diffio-4.7-flash";
61
63
  const SUPPORTED_MODEL_KEYS = Object.keys(MODEL_ENDPOINTS);
62
64
  const hasOwn = (record, key) => Object.prototype.hasOwnProperty.call(record, key);
63
65
  /** Returns the generation endpoint for a model key, or undefined when the SDK does not support it. */
64
66
  function generationEndpointForModel(model) {
65
- const modelKey = hasOwn(LEGACY_MODEL_KEYS, model) ? LEGACY_MODEL_KEYS[model] : model;
67
+ const modelKey = hasOwn(DEPRECATED_MODEL_KEYS, model) ? DEPRECATED_MODEL_KEYS[model] : model;
66
68
  return hasOwn(MODEL_ENDPOINTS, modelKey) ? MODEL_ENDPOINTS[modelKey] : undefined;
67
69
  }
68
70
  /** Per-request timeout for one edge upload call; a 32 MiB part needs about 1 Mbit/s to finish in time. */
@@ -1,11 +1,11 @@
1
1
  import type { DiffioClient } from "../../../../Client";
2
- import type { AudioIsolationResult, GenerationProgressResponse, ModelKey, RestoreMetadata } from "../../../types";
2
+ import type { AcceptedModelKey, AudioIsolationResult, GenerationProgressResponse, RestoreMetadata } from "../../../types";
3
3
  export interface AudioIsolationRestoreOptions {
4
4
  filePath: string;
5
5
  contentType?: string;
6
6
  contentLength?: number;
7
7
  fileFormat?: string;
8
- model?: ModelKey;
8
+ model?: AcceptedModelKey;
9
9
  sampling?: Record<string, unknown>;
10
10
  projectParams?: Record<string, unknown>;
11
11
  generationParams?: Record<string, unknown>;
@@ -26,7 +26,7 @@ export interface AudioIsolationIsolateOptions {
26
26
  contentType?: string;
27
27
  contentLength?: number;
28
28
  fileFormat?: string;
29
- model?: ModelKey;
29
+ model?: AcceptedModelKey;
30
30
  sampling?: Record<string, unknown>;
31
31
  projectParams?: Record<string, unknown>;
32
32
  generationParams?: Record<string, unknown>;
@@ -1,8 +1,8 @@
1
1
  import type { DiffioClient } from "../../../../Client";
2
- import type { CreateGenerationResponse, GenerationDownloadResponse, GenerationProgressResponse, ModelKey } from "../../../types";
2
+ import type { AcceptedModelKey, CreateGenerationResponse, GenerationDownloadResponse, GenerationProgressResponse } from "../../../types";
3
3
  export interface GenerationCreateOptions {
4
4
  apiProjectId: string;
5
- model?: ModelKey;
5
+ model?: AcceptedModelKey;
6
6
  sampling?: Record<string, unknown>;
7
7
  params?: Record<string, unknown>;
8
8
  idempotencyKey?: string;
@@ -117,8 +117,10 @@ function parseGenerationProgressResponse(data) {
117
117
  ...(stageProgress ? { stageProgress } : {}),
118
118
  ...(queue ? { queue } : {}),
119
119
  ...(transcription ? { transcription } : {}),
120
+ warnings: parseGenerationWarnings(data?.warnings),
120
121
  error: data.error ?? null,
121
- errorDetails: data.errorDetails ?? null
122
+ errorDetails: data.errorDetails ?? null,
123
+ ...(typeof data?.retryable === "boolean" ? { retryable: data.retryable } : {})
122
124
  };
123
125
  }
124
126
  function parseGenerationDownloadResponse(data) {
@@ -181,6 +183,7 @@ function parseWebhookConfigureResponse(data) {
181
183
  }
182
184
  function parseGenerationWebhookEvent(data) {
183
185
  const transcription = parseGenerationTranscription(data?.transcription);
186
+ const warnings = parseGenerationWarnings(data?.warnings);
184
187
  return {
185
188
  eventType: data.eventType,
186
189
  eventId: data.eventId,
@@ -192,8 +195,10 @@ function parseGenerationWebhookEvent(data) {
192
195
  hasVideo: data.hasVideo ?? null,
193
196
  modelKey: data.modelKey ?? null,
194
197
  ...(transcription ? { transcription } : {}),
198
+ ...(warnings.length > 0 ? { warnings } : {}),
195
199
  error: data.error ?? null,
196
- errorDetails: data.errorDetails ?? null
200
+ errorDetails: data.errorDetails ?? null,
201
+ ...(typeof data?.retryable === "boolean" ? { retryable: data.retryable } : {})
197
202
  };
198
203
  }
199
204
  const optionalNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
@@ -242,6 +247,28 @@ function parseGenerationTranscription(data) {
242
247
  }
243
248
  return undefined;
244
249
  }
250
+ /** Keeps the warnings with a known code and well-formed fields; anything else in the array is dropped. */
251
+ function parseGenerationWarnings(data) {
252
+ if (!Array.isArray(data)) {
253
+ return [];
254
+ }
255
+ const warnings = [];
256
+ for (const item of data) {
257
+ if (item == null || typeof item !== "object" || Array.isArray(item)) {
258
+ continue;
259
+ }
260
+ const { code, languages, message } = item;
261
+ if (code !== "unsupported_language" || !Array.isArray(languages) || typeof message !== "string") {
262
+ continue;
263
+ }
264
+ warnings.push({
265
+ code,
266
+ languages: languages.filter((language) => typeof language === "string" && language !== ""),
267
+ message
268
+ });
269
+ }
270
+ return warnings;
271
+ }
245
272
  function createAudioIsolationResult(project, generation) {
246
273
  return { project, generation };
247
274
  }
@@ -1,5 +1,14 @@
1
- /** Models new generations can use (api/model_registry.json in diffio-ui); each has its own endpoint. */
2
- export type ModelKey = "diffio-4.6-flash" | "diffio-4.6-pro";
1
+ /** Current models for new generations (api/model_registry.json in diffio-ui); each has its own endpoint. */
2
+ export type ModelKey = "diffio-4.7-flash" | "diffio-4.7-pro";
3
+ /**
4
+ * Older model names the SDK still accepts. Each runs the matching Diffio 4.7 model on its endpoint:
5
+ * the `-flash` names run `diffio-4.7-flash` and the `-pro` names run `diffio-4.7-pro`.
6
+ *
7
+ * @deprecated Use `diffio-4.7-flash` or `diffio-4.7-pro`.
8
+ */
9
+ export type DeprecatedModelKey = "diffio-4.6-flash" | "diffio-4.6-pro" | "diffio-4.5-flash" | "diffio-4.5-pro";
10
+ /** Every value the `model` option accepts: a current {@link ModelKey} or a deprecated alias of one. */
11
+ export type AcceptedModelKey = ModelKey | DeprecatedModelKey;
3
12
  export type DownloadType = "audio" | "video" | "transcript";
4
13
  export type WebhookMode = "test" | "live";
5
14
  export type WebhookEventType = "generation.queued" | "generation.processing" | "generation.failed" | "generation.completed";
@@ -8,6 +17,17 @@ export type TranscriptionStatus = "pending" | "available" | "unavailable";
8
17
  export interface GenerationTranscription {
9
18
  status: TranscriptionStatus;
10
19
  }
20
+ /** Warning codes the SDK knows; warnings with other codes are left out of parsed responses. */
21
+ export type GenerationWarningCode = "unsupported_language";
22
+ /** Something about a generation's recording to know about; the generation still runs. */
23
+ export interface GenerationWarning {
24
+ /** `unsupported_language`: the transcript has speech in a language Diffio does not support yet. */
25
+ code: GenerationWarningCode;
26
+ /** ISO 639-1 base codes such as `ja`, the language with the most words first. */
27
+ languages: string[];
28
+ /** A readable explanation, for example that the result probably won't be usable. */
29
+ message: string;
30
+ }
11
31
  /** The edge upload session create_project opened; the upload token stays inside the SDK. */
12
32
  export interface ProjectUploadSession {
13
33
  uploadSessionId: string;
@@ -110,8 +130,12 @@ export interface GenerationProgressResponse {
110
130
  queue?: GenerationQueueStatus;
111
131
  /** Independent of media completion; omitted by older API versions. */
112
132
  transcription?: GenerationTranscription;
133
+ /** Empty until the transcript is ready, and when older API versions omit it. */
134
+ warnings: GenerationWarning[];
113
135
  error?: string | null;
114
136
  errorDetails?: string | null;
137
+ /** Present with `error`; true when a new generation for the same project can retry the failure. */
138
+ retryable?: boolean;
115
139
  }
116
140
  export interface GenerationDownloadResponse {
117
141
  generationId: string;
@@ -175,8 +199,12 @@ export interface GenerationWebhookEvent {
175
199
  modelKey?: string | null;
176
200
  /** A completed generation may still have a pending or unavailable transcript. */
177
201
  transcription?: GenerationTranscription;
202
+ /** Present only when the generation has warnings. */
203
+ warnings?: GenerationWarning[];
178
204
  error?: string | null;
179
205
  errorDetails?: string | null;
206
+ /** On `generation.failed`: true when a new generation for the same project can fix the failure. */
207
+ retryable?: boolean;
180
208
  }
181
209
  export interface RestoreMetadata {
182
210
  ok: boolean;
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const DIFFIO_SDK_VERSION = "0.3.37";
1
+ export declare const DIFFIO_SDK_VERSION = "0.4.0";
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DIFFIO_SDK_VERSION = void 0;
4
- exports.DIFFIO_SDK_VERSION = "0.3.37";
4
+ exports.DIFFIO_SDK_VERSION = "0.4.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "diffio",
3
- "version": "0.3.37",
3
+ "version": "0.4.0",
4
4
  "description": "Diffio API client for Node.js",
5
5
  "repository": {
6
6
  "type": "git",