@lumavox/server 0.2.1 → 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 +21 -16
- package/dist/errors.d.ts +24 -16
- package/dist/errors.js +21 -40
- package/dist/gen/index.d.ts +1 -1
- package/dist/gen/types.gen.d.ts +1767 -1750
- package/dist/index.d.ts +2 -1
- package/dist/paging.d.ts +19 -29
- package/dist/paging.js +17 -32
- package/dist/resources/agents.d.ts +10 -5
- package/dist/resources/agents.js +9 -3
- package/dist/resources/assets.d.ts +14 -9
- package/dist/resources/assets.js +16 -11
- package/dist/resources/end-users.d.ts +25 -18
- package/dist/resources/end-users.js +47 -43
- package/dist/resources/ephemeral-keys.d.ts +9 -9
- package/dist/resources/ephemeral-keys.js +9 -12
- package/dist/resources/generations.d.ts +3 -3
- package/dist/resources/generations.js +3 -7
- package/dist/resources/knowledge.d.ts +11 -12
- package/dist/resources/knowledge.js +8 -13
- package/dist/resources/resource.d.ts +12 -22
- package/dist/resources/resource.js +21 -4
- package/dist/resources/speech.d.ts +10 -21
- package/dist/resources/speech.js +4 -4
- package/dist/resources/templates.d.ts +4 -2
- package/dist/resources/templates.js +5 -1
- package/dist/resources/usage.d.ts +2 -2
- package/dist/resources/voices.d.ts +8 -6
- package/dist/resources/voices.js +8 -6
- package/dist/transport.d.ts +7 -3
- package/dist/transport.js +40 -19
- package/dist/upload.d.ts +7 -5
- package/dist/upload.js +8 -2
- package/dist/wait.d.ts +5 -9
- package/dist/wait.js +3 -3
- package/package.json +1 -1
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* - **Each read sees its own capability**: an image's id is a 404 on
|
|
16
16
|
* `videos.get`. `generations.get` reads any the key may generate.
|
|
17
17
|
*/
|
|
18
|
-
import type { GenerationInfo, GenerationPage, ListGenerationsData,
|
|
18
|
+
import type { GenerationInfo, GenerationPage, ListGenerationsData, SkyboxStylePage } from "../gen/index.js";
|
|
19
19
|
import type { RequestOptions } from "../transport.js";
|
|
20
20
|
import { Polled } from "./resource.js";
|
|
21
21
|
export type GenerationListParams = NonNullable<ListGenerationsData["query"]>;
|
|
@@ -28,8 +28,8 @@ export declare class Jobs<Body> extends Polled<GenerationInfo> {
|
|
|
28
28
|
}
|
|
29
29
|
/** `/v1/skybox`, and the provider's styles. */
|
|
30
30
|
export declare class Skybox<Body> extends Jobs<Body> {
|
|
31
|
-
/** The styles available now, each
|
|
32
|
-
styles(options?: RequestOptions): Promise<
|
|
31
|
+
/** The styles available now, in one page: each `id` is a `style_id`; none when the provider is unreachable. */
|
|
32
|
+
styles(options?: RequestOptions): Promise<SkyboxStylePage>;
|
|
33
33
|
}
|
|
34
34
|
/** Every generation the key may make, read-only. */
|
|
35
35
|
export declare class Generations extends Polled<GenerationInfo> {
|
|
@@ -15,10 +15,9 @@
|
|
|
15
15
|
* - **Each read sees its own capability**: an image's id is a 404 on
|
|
16
16
|
* `videos.get`. `generations.get` reads any the key may generate.
|
|
17
17
|
*/
|
|
18
|
-
import { byCursor } from "../paging.js";
|
|
19
18
|
import { poll } from "../wait.js";
|
|
20
19
|
import { Polled } from "./resource.js";
|
|
21
|
-
/** The route's
|
|
20
|
+
/** The route's largest page. */
|
|
22
21
|
const PAGE = 100;
|
|
23
22
|
/** One capability's queue: `/v1/images`, `/v1/videos`, … */
|
|
24
23
|
export class Jobs extends Polled {
|
|
@@ -34,7 +33,7 @@ export class Jobs extends Polled {
|
|
|
34
33
|
}
|
|
35
34
|
/** `/v1/skybox`, and the provider's styles. */
|
|
36
35
|
export class Skybox extends Jobs {
|
|
37
|
-
/** The styles available now, each
|
|
36
|
+
/** The styles available now, in one page: each `id` is a `style_id`; none when the provider is unreachable. */
|
|
38
37
|
styles(options) {
|
|
39
38
|
return this.send("GET", "/styles", options);
|
|
40
39
|
}
|
|
@@ -47,9 +46,6 @@ export class Generations extends Polled {
|
|
|
47
46
|
}
|
|
48
47
|
/** Every generation, newest first, page after page (100 a page by default). */
|
|
49
48
|
list(params = {}, options) {
|
|
50
|
-
return
|
|
51
|
-
const page = await this.page({ limit: PAGE, ...params, cursor }, options);
|
|
52
|
-
return { items: page.generations, next: page.next_cursor };
|
|
53
|
-
});
|
|
49
|
+
return this.each("", params, options, PAGE);
|
|
54
50
|
}
|
|
55
51
|
}
|
|
@@ -10,27 +10,26 @@
|
|
|
10
10
|
* - **`upload(file, fields)`** is the ticket, the `PUT` and `fromFile` in
|
|
11
11
|
* one (`upload.ts`); the file's extension says how it is read, 10 MB at
|
|
12
12
|
* most.
|
|
13
|
-
* - **`list()` pages by
|
|
14
|
-
* matches.
|
|
13
|
+
* - **`list()` pages by cursor**, 200 a page.
|
|
15
14
|
* - **`update` with `expected_version`** refuses an edit made over
|
|
16
|
-
* somebody else's (409); `delete` answers
|
|
17
|
-
*
|
|
15
|
+
* somebody else's (409); `delete` answers `true`, and `false` for one
|
|
16
|
+
* already gone.
|
|
18
17
|
*/
|
|
19
|
-
import type {
|
|
18
|
+
import type { GetKnowledgeInsightsData, KnowledgeAgentsUpdate, KnowledgeAssigned, KnowledgeBulk, KnowledgeBulkResult, KnowledgeCategoryPage, KnowledgeCreate, KnowledgeFileCreate, KnowledgeInfo, KnowledgeInsights, KnowledgePage, KnowledgeSearchRequest, KnowledgeSearchResult, KnowledgeUpdate, KnowledgeUploadRequest, KnowledgeUploadTicket, KnowledgeUrlCreate, ListKnowledgeData } from "../gen/index.js";
|
|
20
19
|
import type { RequestOptions } from "../transport.js";
|
|
21
20
|
import { type UploadData, type UploadOptions } from "../upload.js";
|
|
22
21
|
import { Waitable } from "./resource.js";
|
|
23
22
|
export type KnowledgeListParams = NonNullable<ListKnowledgeData["query"]>;
|
|
24
|
-
export type KnowledgeInsightsParams = NonNullable<
|
|
23
|
+
export type KnowledgeInsightsParams = NonNullable<GetKnowledgeInsightsData["query"]>;
|
|
25
24
|
/** A file's entry: `fromFile`'s fields, and its type when not its extension's. */
|
|
26
25
|
export type KnowledgeUploadFields = Omit<KnowledgeFileCreate, "upload_id"> & {
|
|
27
26
|
content_type?: string | null;
|
|
28
27
|
};
|
|
29
28
|
export declare class Knowledge extends Waitable<KnowledgeInfo, KnowledgeUpdate> {
|
|
30
|
-
/** One page, with the `
|
|
31
|
-
page(params?: KnowledgeListParams, options?: RequestOptions): Promise<
|
|
29
|
+
/** One page, with the `next_cursor` of the next. */
|
|
30
|
+
page(params?: KnowledgeListParams, options?: RequestOptions): Promise<KnowledgePage>;
|
|
32
31
|
/** Every entry the filter matches, page after page (200 a page by default). */
|
|
33
|
-
list(params?: Omit<KnowledgeListParams, "
|
|
32
|
+
list(params?: Omit<KnowledgeListParams, "cursor">, options?: RequestOptions): AsyncGenerator<KnowledgeInfo, void, undefined>;
|
|
34
33
|
/** A written entry, indexed after it is saved. */
|
|
35
34
|
create(body: KnowledgeCreate, options?: RequestOptions): Promise<KnowledgeInfo>;
|
|
36
35
|
/** Many written entries at once: what was made, and what was refused. */
|
|
@@ -48,11 +47,11 @@ export declare class Knowledge extends Waitable<KnowledgeInfo, KnowledgeUpdate>
|
|
|
48
47
|
/** Reads its page again now. */
|
|
49
48
|
refresh(id: string, options?: RequestOptions): Promise<KnowledgeInfo>;
|
|
50
49
|
/** Replaces the agents that may look it up. */
|
|
51
|
-
setAgents(id: string, body:
|
|
50
|
+
setAgents(id: string, body: KnowledgeAgentsUpdate, options?: RequestOptions): Promise<KnowledgeAssigned>;
|
|
52
51
|
/** What an agent would find for a question. */
|
|
53
52
|
search(body: KnowledgeSearchRequest, options?: RequestOptions): Promise<KnowledgeSearchResult>;
|
|
54
|
-
/** The categories in use. */
|
|
55
|
-
categories(options?: RequestOptions): Promise<
|
|
53
|
+
/** The categories in use, in one page. */
|
|
54
|
+
categories(options?: RequestOptions): Promise<KnowledgeCategoryPage>;
|
|
56
55
|
/** What was looked up, and what went unanswered: 7 days by default. */
|
|
57
56
|
insights(params?: KnowledgeInsightsParams, options?: RequestOptions): Promise<KnowledgeInsights>;
|
|
58
57
|
}
|
|
@@ -10,28 +10,23 @@
|
|
|
10
10
|
* - **`upload(file, fields)`** is the ticket, the `PUT` and `fromFile` in
|
|
11
11
|
* one (`upload.ts`); the file's extension says how it is read, 10 MB at
|
|
12
12
|
* most.
|
|
13
|
-
* - **`list()` pages by
|
|
14
|
-
* matches.
|
|
13
|
+
* - **`list()` pages by cursor**, 200 a page.
|
|
15
14
|
* - **`update` with `expected_version`** refuses an edit made over
|
|
16
|
-
* somebody else's (409); `delete` answers
|
|
17
|
-
*
|
|
15
|
+
* somebody else's (409); `delete` answers `true`, and `false` for one
|
|
16
|
+
* already gone.
|
|
18
17
|
*/
|
|
19
|
-
import { byOffset } from "../paging.js";
|
|
20
18
|
import { put, sizeOf, typeOf, } from "../upload.js";
|
|
21
19
|
import { Waitable } from "./resource.js";
|
|
22
|
-
/** The route's
|
|
20
|
+
/** The route's largest page. */
|
|
23
21
|
const PAGE = 200;
|
|
24
22
|
export class Knowledge extends Waitable {
|
|
25
|
-
/** One page, with the `
|
|
23
|
+
/** One page, with the `next_cursor` of the next. */
|
|
26
24
|
page(params = {}, options) {
|
|
27
25
|
return this.send("GET", "", options, params);
|
|
28
26
|
}
|
|
29
27
|
/** Every entry the filter matches, page after page (200 a page by default). */
|
|
30
28
|
list(params = {}, options) {
|
|
31
|
-
return
|
|
32
|
-
const page = await this.page({ ...params, offset, limit }, options);
|
|
33
|
-
return { items: page.entries, total: page.total };
|
|
34
|
-
}, params.limit ?? PAGE);
|
|
29
|
+
return this.each("", params, options, PAGE);
|
|
35
30
|
}
|
|
36
31
|
/** A written entry, indexed after it is saved. */
|
|
37
32
|
create(body, options) {
|
|
@@ -58,7 +53,7 @@ export class Knowledge extends Waitable {
|
|
|
58
53
|
const { content_type, ...body } = fields;
|
|
59
54
|
const ticket = await this.uploadUrl({
|
|
60
55
|
filename: body.filename,
|
|
61
|
-
|
|
56
|
+
size_bytes: sizeOf(file, options.size) ?? null,
|
|
62
57
|
content_type: typeOf(file, content_type) || null,
|
|
63
58
|
}, options);
|
|
64
59
|
await put(this.api, ticket, file, ticket.content_type, options);
|
|
@@ -80,7 +75,7 @@ export class Knowledge extends Waitable {
|
|
|
80
75
|
search(body, options) {
|
|
81
76
|
return this.send("POST", "/search", options, body);
|
|
82
77
|
}
|
|
83
|
-
/** The categories in use. */
|
|
78
|
+
/** The categories in use, in one page. */
|
|
84
79
|
categories(options) {
|
|
85
80
|
return this.send("GET", "/categories", options);
|
|
86
81
|
}
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* What every resource shares, as a ladder of bases each method is written
|
|
3
|
-
* once in — the SDK's size is a budget (`test/dist.test.ts`):
|
|
4
|
-
*
|
|
5
|
-
* - **`Resource`**: the transport, and the path its routes start with.
|
|
6
|
-
* `send` takes the rest of the path, and `at(id)` is one item's, the id
|
|
7
|
-
* encoded (an id the caller holds may carry `/` or `?`).
|
|
8
|
-
* - **`Readable`**: `get(id)`; **`Polled`** adds `wait(id)` (`wait.ts`),
|
|
9
|
-
* for a generation, which is read and waited on and nothing else.
|
|
10
|
-
* - **`Editable`**: `update(id, body)` (`PATCH`) and `delete(id)`, which
|
|
11
|
-
* answers `null` when there is nothing by that id — already done.
|
|
12
|
-
* - **`Waitable`**: an editable whose items are jobs — a voice, an asset,
|
|
13
|
-
* a knowledge entry — with `wait(id)` and `settled`, which an upload
|
|
14
|
-
* answers through.
|
|
15
|
-
*
|
|
16
|
-
* Fields are `declare`d, not defined: each is assigned in a constructor,
|
|
17
|
-
* and a definition is bytes in every customer's bundle.
|
|
18
|
-
*/
|
|
19
1
|
import { type Method, type RequestOptions, type Transport } from "../transport.js";
|
|
20
2
|
import type { UploadOptions } from "../upload.js";
|
|
21
3
|
import { type Job } from "../wait.js";
|
|
@@ -27,6 +9,12 @@ export declare class Resource {
|
|
|
27
9
|
protected send<T>(method: Method, rest: string, options?: RequestOptions, data?: unknown): Promise<T>;
|
|
28
10
|
/** The rest of item `id`'s path, and of what follows it. */
|
|
29
11
|
protected at(id: string, rest?: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Every item of the list at `base` + `rest`, page after page: `query`,
|
|
14
|
+
* then each page's cursor. `limit` is the route's largest page unless
|
|
15
|
+
* the query names one — fewer calls for a long list.
|
|
16
|
+
*/
|
|
17
|
+
protected each<T>(rest: string, query?: object, options?: RequestOptions, limit?: number): AsyncGenerator<T, void, undefined>;
|
|
30
18
|
}
|
|
31
19
|
export declare class Readable<Item> extends Resource {
|
|
32
20
|
/** One of them. A `NotFoundError` when there is none. */
|
|
@@ -36,15 +24,17 @@ export declare class Polled<Item extends Job> extends Readable<Item> {
|
|
|
36
24
|
/** Reads it until its `status` is final (`wait.ts`). */
|
|
37
25
|
wait(id: string, options?: RequestOptions): Promise<Item>;
|
|
38
26
|
}
|
|
39
|
-
export declare class Editable<Item, Update, Updated = Item, Deleted =
|
|
27
|
+
export declare class Editable<Item, Update, Updated = Item, Deleted = boolean> extends Readable<Item> {
|
|
40
28
|
/** Changes what `body` gives; absent fields are untouched. */
|
|
41
29
|
update(id: string, body: Update, options?: RequestOptions): Promise<Updated>;
|
|
42
|
-
/** Deletes it
|
|
43
|
-
delete(id: string, options?: RequestOptions): Promise<Deleted
|
|
30
|
+
/** Deletes it: `true`, or `false` when there is none by that id — already done. */
|
|
31
|
+
delete(id: string, options?: RequestOptions): Promise<Deleted>;
|
|
32
|
+
/** The `DELETE` itself: its answer, `undefined` for a 204, `null` for a 404. */
|
|
33
|
+
protected drop<T>(id: string, options?: RequestOptions): Promise<T | null>;
|
|
44
34
|
}
|
|
45
35
|
export declare class Waitable<Item extends Job & {
|
|
46
36
|
id: string;
|
|
47
|
-
}, Update, Updated = Item
|
|
37
|
+
}, Update, Updated = Item> extends Editable<Item, Update, Updated> {
|
|
48
38
|
/** Reads it until its `status` is final (`wait.ts`). */
|
|
49
39
|
wait(id: string, options?: RequestOptions): Promise<Item>;
|
|
50
40
|
/** `item` as made, or as it ended when `options.wait` says to wait. */
|
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
*
|
|
5
5
|
* - **`Resource`**: the transport, and the path its routes start with.
|
|
6
6
|
* `send` takes the rest of the path, and `at(id)` is one item's, the id
|
|
7
|
-
* encoded (an id the caller holds may carry `/` or `?`).
|
|
7
|
+
* encoded (an id the caller holds may carry `/` or `?`). `each` is a
|
|
8
|
+
* list's every item, page after page (`paging.ts`).
|
|
8
9
|
* - **`Readable`**: `get(id)`; **`Polled`** adds `wait(id)` (`wait.ts`),
|
|
9
10
|
* for a generation, which is read and waited on and nothing else.
|
|
10
|
-
* - **`Editable`**: `update(id, body)` (`PATCH`) and `delete(id)
|
|
11
|
-
*
|
|
11
|
+
* - **`Editable`**: `update(id, body)` (`PATCH`) and `delete(id)`. A
|
|
12
|
+
* delete of one thing is a 204 with no body, so it answers `true`, and
|
|
13
|
+
* `false` when there is nothing by that id — already done. One that
|
|
14
|
+
* reports what went with it (an end user's, a folder's) answers those
|
|
15
|
+
* counts, and `null` for nothing by that id: the same rule, with a body.
|
|
12
16
|
* - **`Waitable`**: an editable whose items are jobs — a voice, an asset,
|
|
13
17
|
* a knowledge entry — with `wait(id)` and `settled`, which an upload
|
|
14
18
|
* answers through.
|
|
@@ -16,6 +20,7 @@
|
|
|
16
20
|
* Fields are `declare`d, not defined: each is assigned in a constructor,
|
|
17
21
|
* and a definition is bytes in every customer's bundle.
|
|
18
22
|
*/
|
|
23
|
+
import { pages } from "../paging.js";
|
|
19
24
|
import { orNull, segment, } from "../transport.js";
|
|
20
25
|
import { poll } from "../wait.js";
|
|
21
26
|
export class Resource {
|
|
@@ -31,6 +36,14 @@ export class Resource {
|
|
|
31
36
|
at(id, rest = "") {
|
|
32
37
|
return `/${segment(id)}${rest}`;
|
|
33
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Every item of the list at `base` + `rest`, page after page: `query`,
|
|
41
|
+
* then each page's cursor. `limit` is the route's largest page unless
|
|
42
|
+
* the query names one — fewer calls for a long list.
|
|
43
|
+
*/
|
|
44
|
+
each(rest, query, options, limit) {
|
|
45
|
+
return pages((cursor) => this.send("GET", rest, options, { limit, ...query, cursor }));
|
|
46
|
+
}
|
|
34
47
|
}
|
|
35
48
|
export class Readable extends Resource {
|
|
36
49
|
/** One of them. A `NotFoundError` when there is none. */
|
|
@@ -49,8 +62,12 @@ export class Editable extends Readable {
|
|
|
49
62
|
update(id, body, options) {
|
|
50
63
|
return this.send("PATCH", this.at(id), options, body);
|
|
51
64
|
}
|
|
52
|
-
/** Deletes it
|
|
65
|
+
/** Deletes it: `true`, or `false` when there is none by that id — already done. */
|
|
53
66
|
delete(id, options) {
|
|
67
|
+
return this.drop(id, options).then((gone) => gone !== null);
|
|
68
|
+
}
|
|
69
|
+
/** The `DELETE` itself: its answer, `undefined` for a 204, `null` for a 404. */
|
|
70
|
+
drop(id, options) {
|
|
54
71
|
return orNull(this.send("DELETE", this.at(id), options));
|
|
55
72
|
}
|
|
56
73
|
}
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
*
|
|
7
7
|
* - **`tts.create(body)` answers the audio whole** (an `ArrayBuffer`, WAV
|
|
8
8
|
* or raw `pcm`) **or, with `stream: true`, as it is made** (a
|
|
9
|
-
* `ReadableStream` of `pcm`), beside what its headers say.
|
|
10
|
-
*
|
|
11
|
-
* so its rate is the one asked
|
|
12
|
-
* `@ino/core/speech/catalog
|
|
9
|
+
* `ReadableStream` of `pcm`), beside what its headers say. Both name
|
|
10
|
+
* their sample rate (`X-Sample-Rate`); a stream from an API before
|
|
11
|
+
* 0.31.10 named none, so without the header its rate is the one asked
|
|
12
|
+
* for, 24 000 Hz unset (the API's default, `@ino/core/speech/catalog`).
|
|
13
13
|
* - **`stt.create(audio, params)` sends the audio as the body**, the
|
|
14
14
|
* options as the query — the route's raw form, which a stream can be
|
|
15
15
|
* sent as, unlike a multipart one. It answers the transcript, or with
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* only). Up to 25 MB.
|
|
18
18
|
* - **A stream's timeout ends at its headers**; `signal` still ends it.
|
|
19
19
|
*/
|
|
20
|
-
import type {
|
|
20
|
+
import type { TranscribeData, Transcription, TranscriptionStreamLine, TtsRequest } from "../gen/index.js";
|
|
21
21
|
import type { RequestOptions } from "../transport.js";
|
|
22
22
|
import { type UploadData } from "../upload.js";
|
|
23
23
|
import { Resource } from "./resource.js";
|
|
@@ -51,23 +51,12 @@ export type SttParams = Omit<TranscribeData["body"], "file"> & {
|
|
|
51
51
|
content_type?: string;
|
|
52
52
|
};
|
|
53
53
|
/**
|
|
54
|
-
* `POST /v1/stt`'s whole answer
|
|
55
|
-
* (
|
|
56
|
-
* `apps/api/src/routes/stt.ts`), written out; `apps/api/test/sdk.test.ts`
|
|
57
|
-
* holds the two together.
|
|
54
|
+
* `POST /v1/stt`'s whole answer, as the document declares it since api
|
|
55
|
+
* 0.31.10 (`Transcription`). The name the SDK has always exported.
|
|
58
56
|
*/
|
|
59
|
-
export
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
language_probability: number | null;
|
|
63
|
-
/** What was charged, per minute. */
|
|
64
|
-
duration_seconds: number;
|
|
65
|
-
model: string;
|
|
66
|
-
/** With `timestamps: true`; `null` otherwise. */
|
|
67
|
-
words: TranscriptWord[] | null;
|
|
68
|
-
}
|
|
69
|
-
/** One line of a streamed transcript. */
|
|
70
|
-
export type SttEvent = StreamSegment | StreamTranscript | StreamError | StreamDone;
|
|
57
|
+
export type Transcript = Transcription;
|
|
58
|
+
/** One line of a streamed transcript: a `segment`, its `transcript` or `error`, and the `done`. */
|
|
59
|
+
export type SttEvent = TranscriptionStreamLine;
|
|
71
60
|
export declare class Stt extends Resource {
|
|
72
61
|
/** The transcript as it is made: an iterator of its events. */
|
|
73
62
|
create(audio: UploadData, params: SttParams & {
|
package/dist/resources/speech.js
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
*
|
|
7
7
|
* - **`tts.create(body)` answers the audio whole** (an `ArrayBuffer`, WAV
|
|
8
8
|
* or raw `pcm`) **or, with `stream: true`, as it is made** (a
|
|
9
|
-
* `ReadableStream` of `pcm`), beside what its headers say.
|
|
10
|
-
*
|
|
11
|
-
* so its rate is the one asked
|
|
12
|
-
* `@ino/core/speech/catalog
|
|
9
|
+
* `ReadableStream` of `pcm`), beside what its headers say. Both name
|
|
10
|
+
* their sample rate (`X-Sample-Rate`); a stream from an API before
|
|
11
|
+
* 0.31.10 named none, so without the header its rate is the one asked
|
|
12
|
+
* for, 24 000 Hz unset (the API's default, `@ino/core/speech/catalog`).
|
|
13
13
|
* - **`stt.create(audio, params)` sends the audio as the body**, the
|
|
14
14
|
* options as the query — the route's raw form, which a stream can be
|
|
15
15
|
* sent as, unlike a multipart one. It answers the transcript, or with
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - **`file(id, name)` needs no key** and answers the bytes; a template's
|
|
12
12
|
* URLs already name each file and its `v`, which makes it cacheable.
|
|
13
13
|
*/
|
|
14
|
-
import type { GenerationInfo, TemplateGenerateRequest, TemplateInfo,
|
|
14
|
+
import type { GenerationInfo, TemplateGenerateRequest, TemplateInfo, TemplatePage } from "../gen/index.js";
|
|
15
15
|
import { type RequestOptions, type Transport } from "../transport.js";
|
|
16
16
|
import type { Generations } from "./generations.js";
|
|
17
17
|
import { Readable } from "./resource.js";
|
|
@@ -24,8 +24,10 @@ export interface TemplateFile {
|
|
|
24
24
|
export declare class Templates extends Readable<TemplateInfo> {
|
|
25
25
|
private readonly generations;
|
|
26
26
|
constructor(api: Transport, base: string, generations: Generations);
|
|
27
|
+
/** The page of templates, as the route answers it: all of them, `next_cursor` `null`. */
|
|
28
|
+
page(options?: RequestOptions): Promise<TemplatePage>;
|
|
27
29
|
/** Every template this organisation may generate from. */
|
|
28
|
-
list(options?: RequestOptions):
|
|
30
|
+
list(options?: RequestOptions): AsyncGenerator<TemplateInfo, void, undefined>;
|
|
29
31
|
/** Generates from it, charged when accepted: the `gen_…` at once. */
|
|
30
32
|
create(id: string, body?: TemplateGenerateRequest, options?: RequestOptions): Promise<GenerationInfo>;
|
|
31
33
|
/** Generates from it and waits: the generation once it is final. */
|
|
@@ -20,9 +20,13 @@ export class Templates extends Readable {
|
|
|
20
20
|
super(api, base);
|
|
21
21
|
this.generations = generations;
|
|
22
22
|
}
|
|
23
|
+
/** The page of templates, as the route answers it: all of them, `next_cursor` `null`. */
|
|
24
|
+
page(options) {
|
|
25
|
+
return this.send("GET", "", options);
|
|
26
|
+
}
|
|
23
27
|
/** Every template this organisation may generate from. */
|
|
24
28
|
list(options) {
|
|
25
|
-
return this.
|
|
29
|
+
return this.each("", {}, options);
|
|
26
30
|
}
|
|
27
31
|
/** Generates from it, charged when accepted: the `gen_…` at once. */
|
|
28
32
|
create(id, body = {}, options) {
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* window of days, and `GET /v1/plan`, its plan and balance (`null` with
|
|
4
4
|
* no subscription). Read-only, unmetered.
|
|
5
5
|
*/
|
|
6
|
-
import type {
|
|
6
|
+
import type { GetUsageData, OrgPlan, UsageResponse } from "../gen/index.js";
|
|
7
7
|
import type { RequestOptions } from "../transport.js";
|
|
8
8
|
import { Resource } from "./resource.js";
|
|
9
|
-
export type UsageParams = NonNullable<
|
|
9
|
+
export type UsageParams = NonNullable<GetUsageData["query"]>;
|
|
10
10
|
export declare class Usage extends Resource {
|
|
11
11
|
/** Requests and seconds by capability, by day and by key: 30 days by default. */
|
|
12
12
|
get(params?: UsageParams, options?: RequestOptions): Promise<UsageResponse>;
|
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
* create in one (`upload.ts`); `consent: true` says you may clone it.
|
|
10
10
|
* - **`design(body)` answers previews, not a voice**: keep one with
|
|
11
11
|
* `saveDesign`. It is a provider call held open, and charged.
|
|
12
|
-
* - **`delete` answers `false` when there was no such
|
|
12
|
+
* - **`delete` answers `true`**, and `false` when there was no such
|
|
13
|
+
* voice: done.
|
|
14
|
+
* - **`list()` reads one page**: the route answers every voice in it.
|
|
13
15
|
*/
|
|
14
|
-
import type { VoiceDesignRequest, VoiceDesignResult, VoiceDesignSaveRequest, VoiceDetail, VoiceInfo, VoiceUpdate, VoiceUpload, VoiceUploadRequest, VoiceUploadTicket } from "../gen/index.js";
|
|
16
|
+
import type { VoiceDesignRequest, VoiceDesignResult, VoiceDesignSaveRequest, VoiceDetail, VoiceInfo, VoiceInfoPage, VoiceUpdate, VoiceUpload, VoiceUploadRequest, VoiceUploadTicket } from "../gen/index.js";
|
|
15
17
|
import type { RequestOptions } from "../transport.js";
|
|
16
18
|
import { type UploadData, type UploadOptions } from "../upload.js";
|
|
17
19
|
import { Waitable } from "./resource.js";
|
|
@@ -21,17 +23,17 @@ export type VoiceUploadFields = Omit<VoiceUpload, "upload_id"> & {
|
|
|
21
23
|
content_type?: string;
|
|
22
24
|
};
|
|
23
25
|
/** `update` renames a voice, or changes its description or defaults. */
|
|
24
|
-
export declare class Voices extends Waitable<VoiceDetail, VoiceUpdate
|
|
26
|
+
export declare class Voices extends Waitable<VoiceDetail, VoiceUpdate> {
|
|
27
|
+
/** The page of voices, as the route answers it: all of them, `next_cursor` `null`. */
|
|
28
|
+
page(options?: RequestOptions): Promise<VoiceInfoPage>;
|
|
25
29
|
/** Every voice this organisation may speak with. */
|
|
26
|
-
list(options?: RequestOptions):
|
|
30
|
+
list(options?: RequestOptions): AsyncGenerator<VoiceInfo, void, undefined>;
|
|
27
31
|
/** Clones a recording already `PUT` to its ticket: `pending` at once. */
|
|
28
32
|
create(body: VoiceUpload, options?: RequestOptions): Promise<VoiceDetail>;
|
|
29
33
|
/** A signed URL to `PUT` a recording to, with exactly this type. */
|
|
30
34
|
uploadUrl(body: VoiceUploadRequest, options?: RequestOptions): Promise<VoiceUploadTicket>;
|
|
31
35
|
/** Uploads a recording and clones it: `uploadUrl`, the `PUT`, `create`. */
|
|
32
36
|
upload(recording: UploadData, fields: VoiceUploadFields, options?: UploadOptions): Promise<VoiceDetail>;
|
|
33
|
-
/** Deletes it: `true`, or `false` when there was none by that id (a 204 has no body). */
|
|
34
|
-
delete(id: string, options?: RequestOptions): Promise<boolean>;
|
|
35
37
|
/** Speaks its samples again, one per model. */
|
|
36
38
|
resample(id: string, options?: RequestOptions): Promise<VoiceDetail>;
|
|
37
39
|
/** Previews of a voice made from a description; charged. */
|
package/dist/resources/voices.js
CHANGED
|
@@ -9,15 +9,21 @@
|
|
|
9
9
|
* create in one (`upload.ts`); `consent: true` says you may clone it.
|
|
10
10
|
* - **`design(body)` answers previews, not a voice**: keep one with
|
|
11
11
|
* `saveDesign`. It is a provider call held open, and charged.
|
|
12
|
-
* - **`delete` answers `false` when there was no such
|
|
12
|
+
* - **`delete` answers `true`**, and `false` when there was no such
|
|
13
|
+
* voice: done.
|
|
14
|
+
* - **`list()` reads one page**: the route answers every voice in it.
|
|
13
15
|
*/
|
|
14
16
|
import { needType, put, } from "../upload.js";
|
|
15
17
|
import { Waitable } from "./resource.js";
|
|
16
18
|
/** `update` renames a voice, or changes its description or defaults. */
|
|
17
19
|
export class Voices extends Waitable {
|
|
20
|
+
/** The page of voices, as the route answers it: all of them, `next_cursor` `null`. */
|
|
21
|
+
page(options) {
|
|
22
|
+
return this.send("GET", "", options);
|
|
23
|
+
}
|
|
18
24
|
/** Every voice this organisation may speak with. */
|
|
19
25
|
list(options) {
|
|
20
|
-
return this.
|
|
26
|
+
return this.each("", {}, options);
|
|
21
27
|
}
|
|
22
28
|
/** Clones a recording already `PUT` to its ticket: `pending` at once. */
|
|
23
29
|
create(body, options) {
|
|
@@ -34,10 +40,6 @@ export class Voices extends Waitable {
|
|
|
34
40
|
await put(this.api, ticket, recording, ticket.content_type, options);
|
|
35
41
|
return this.settled(await this.create({ ...body, upload_id: ticket.upload_id }, options), options);
|
|
36
42
|
}
|
|
37
|
-
/** Deletes it: `true`, or `false` when there was none by that id (a 204 has no body). */
|
|
38
|
-
async delete(id, options) {
|
|
39
|
-
return (await super.delete(id, options)) !== null;
|
|
40
|
-
}
|
|
41
43
|
/** Speaks its samples again, one per model. */
|
|
42
44
|
resample(id, options) {
|
|
43
45
|
return this.send("POST", this.at(id, "/sample"), options);
|
package/dist/transport.d.ts
CHANGED
|
@@ -49,9 +49,13 @@ export interface Answer<T> {
|
|
|
49
49
|
}
|
|
50
50
|
/** The longest `Retry-After` slept through; past it the 429 is thrown. */
|
|
51
51
|
export declare const MAX_RETRY_AFTER_S = 60;
|
|
52
|
-
/** A path parameter, encoded: an `external_id` may hold `/` or `?`. */
|
|
53
|
-
export declare const segment: (value: string) => string;
|
|
54
|
-
/**
|
|
52
|
+
/** A path parameter or a query's value, encoded: an `external_id` may hold `/` or `?`. */
|
|
53
|
+
export declare const segment: (value: string | number | boolean) => string;
|
|
54
|
+
/**
|
|
55
|
+
* A request id of the API's own shape: 16 hex. From `Math.random`, not
|
|
56
|
+
* `crypto`, which React Native lacks (this file is the client SDK's too):
|
|
57
|
+
* an id names a call in the logs and is no secret.
|
|
58
|
+
*/
|
|
55
59
|
export declare const newRequestId: () => string;
|
|
56
60
|
/**
|
|
57
61
|
* How long to wait before retry `attempt` (1, 2, …): the doubling backoff
|
package/dist/transport.js
CHANGED
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
* wins, up to a minute. A longer one is thrown at once as a
|
|
27
27
|
* `RateLimitError` with its `retryAfter`: a call that sleeps for an hour
|
|
28
28
|
* is not one a caller can reason about.
|
|
29
|
+
* - **The client SDK runs this file too** (`sdks/client/src/transport.ts`,
|
|
30
|
+
* a copy its `test/copies.test.ts` holds identical), on React Native's
|
|
31
|
+
* Hermes as well: so no `crypto`, `URLSearchParams`, `AbortSignal.any`
|
|
32
|
+
* or global `ReadableStream` taken for granted, each of which it lacks.
|
|
29
33
|
*/
|
|
30
34
|
import { ConnectionError, errorFromResponse, NotFoundError, PlatformError, TimeoutError, } from "./errors.js";
|
|
31
35
|
const RETRIED_STATUS = new Set([429, 502, 503, 504]);
|
|
@@ -33,10 +37,14 @@ const BASE_DELAY_MS = 500;
|
|
|
33
37
|
const MAX_DELAY_MS = 8_000;
|
|
34
38
|
/** The longest `Retry-After` slept through; past it the 429 is thrown. */
|
|
35
39
|
export const MAX_RETRY_AFTER_S = 60;
|
|
36
|
-
/** A path parameter, encoded: an `external_id` may hold `/` or `?`. */
|
|
40
|
+
/** A path parameter or a query's value, encoded: an `external_id` may hold `/` or `?`. */
|
|
37
41
|
export const segment = (value) => encodeURIComponent(value);
|
|
38
|
-
/**
|
|
39
|
-
|
|
42
|
+
/**
|
|
43
|
+
* A request id of the API's own shape: 16 hex. From `Math.random`, not
|
|
44
|
+
* `crypto`, which React Native lacks (this file is the client SDK's too):
|
|
45
|
+
* an id names a call in the logs and is no secret.
|
|
46
|
+
*/
|
|
47
|
+
export const newRequestId = () => "x".repeat(16).replace(/x/g, () => ((Math.random() * 16) | 0).toString(16));
|
|
40
48
|
/**
|
|
41
49
|
* How long to wait before retry `attempt` (1, 2, …): the doubling backoff
|
|
42
50
|
* less up to a quarter, or `Retry-After`'s seconds when the API sent one.
|
|
@@ -76,7 +84,7 @@ export function parsed(text, status, requestId) {
|
|
|
76
84
|
catch (cause) {
|
|
77
85
|
throw new PlatformError({
|
|
78
86
|
status,
|
|
79
|
-
|
|
87
|
+
code: "invalid_response",
|
|
80
88
|
message: `HTTP ${status} with a body that is not JSON.`,
|
|
81
89
|
requestId,
|
|
82
90
|
cause,
|
|
@@ -101,7 +109,8 @@ export class Transport {
|
|
|
101
109
|
}
|
|
102
110
|
async request(call, options = {}) {
|
|
103
111
|
const requestId = options.requestId ?? newRequestId();
|
|
104
|
-
|
|
112
|
+
// A stream by its shape: not every runtime has a global `ReadableStream`.
|
|
113
|
+
const once = "getReader" in Object(call.raw);
|
|
105
114
|
const maxRetries = once
|
|
106
115
|
? 0
|
|
107
116
|
: (options.maxRetries ?? this.config.maxRetries);
|
|
@@ -154,13 +163,13 @@ export class Transport {
|
|
|
154
163
|
throw outcome.kind === "timeout"
|
|
155
164
|
? new TimeoutError({
|
|
156
165
|
status: 0,
|
|
157
|
-
|
|
166
|
+
code: "timeout",
|
|
158
167
|
message: "The API did not answer in time.",
|
|
159
168
|
requestId,
|
|
160
169
|
})
|
|
161
170
|
: new ConnectionError({
|
|
162
171
|
status: 0,
|
|
163
|
-
|
|
172
|
+
code: "connection_error",
|
|
164
173
|
message: "Could not reach the API.",
|
|
165
174
|
requestId,
|
|
166
175
|
cause: outcome.error,
|
|
@@ -170,27 +179,37 @@ export class Transport {
|
|
|
170
179
|
}
|
|
171
180
|
}
|
|
172
181
|
url(call) {
|
|
173
|
-
|
|
182
|
+
// By hand: React Native's `URLSearchParams` is partial.
|
|
183
|
+
let query = "";
|
|
174
184
|
for (const [key, value] of Object.entries(call.query ?? {})) {
|
|
175
|
-
if (value
|
|
176
|
-
|
|
185
|
+
if (value != null) {
|
|
186
|
+
query += `${query ? "&" : "?"}${key}=${segment(value)}`;
|
|
187
|
+
}
|
|
177
188
|
}
|
|
178
|
-
const query = params.toString();
|
|
179
189
|
const base = /^https?:/.test(call.path) ? "" : this.config.baseUrl;
|
|
180
|
-
return
|
|
190
|
+
return base + call.path + query;
|
|
181
191
|
}
|
|
182
192
|
/**
|
|
183
193
|
* One send and its body read, under this attempt's timer — which stops
|
|
184
194
|
* at the headers of a stream the caller reads (and of nothing else).
|
|
185
195
|
*/
|
|
186
196
|
async attempt(url, init, read, options) {
|
|
197
|
+
// The caller's signal joined to the timer by hand, its reason carried
|
|
198
|
+
// over: `AbortSignal.any` is not React Native's. Left joined for a
|
|
199
|
+
// stream, whose body the caller's abort still ends.
|
|
200
|
+
const { signal } = options;
|
|
187
201
|
const timer = new AbortController();
|
|
188
|
-
const
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
|
|
202
|
+
const stop = () => timer.abort(signal?.reason);
|
|
203
|
+
const clock = setTimeout(stop, options.timeoutMs ?? this.config.timeoutMs);
|
|
204
|
+
signal?.addEventListener("abort", stop);
|
|
205
|
+
// Already aborted: no event will come, and `fetch` sends nothing.
|
|
206
|
+
if (signal?.aborted)
|
|
207
|
+
stop();
|
|
192
208
|
try {
|
|
193
|
-
const response = await this.config.fetch(url, {
|
|
209
|
+
const response = await this.config.fetch(url, {
|
|
210
|
+
...init,
|
|
211
|
+
signal: timer.signal,
|
|
212
|
+
});
|
|
194
213
|
const body = !response.ok
|
|
195
214
|
? await response.text()
|
|
196
215
|
: read === "stream"
|
|
@@ -202,14 +221,16 @@ export class Transport {
|
|
|
202
221
|
}
|
|
203
222
|
catch (error) {
|
|
204
223
|
// The caller's abort is the caller's, whatever else happened.
|
|
205
|
-
if (
|
|
206
|
-
throw
|
|
224
|
+
if (signal?.aborted)
|
|
225
|
+
throw signal.reason;
|
|
207
226
|
if (timer.signal.aborted)
|
|
208
227
|
return { kind: "timeout" };
|
|
209
228
|
return { kind: "network", error };
|
|
210
229
|
}
|
|
211
230
|
finally {
|
|
212
231
|
clearTimeout(clock);
|
|
232
|
+
if (read !== "stream")
|
|
233
|
+
signal?.removeEventListener("abort", stop);
|
|
213
234
|
}
|
|
214
235
|
}
|
|
215
236
|
}
|