@lumavox/server 0.5.0 → 0.8.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 +11 -8
- package/dist/client.d.ts +2 -0
- package/dist/client.js +2 -0
- package/dist/gen/index.d.ts +1 -1
- package/dist/gen/types.gen.d.ts +701 -4
- package/dist/index.d.ts +4 -3
- package/dist/resources/agents.d.ts +15 -9
- package/dist/resources/agents.js +12 -17
- package/dist/resources/end-users.d.ts +5 -8
- package/dist/resources/end-users.js +6 -9
- package/dist/resources/ephemeral-keys.d.ts +24 -18
- package/dist/resources/ephemeral-keys.js +27 -20
- package/dist/resources/resource.d.ts +14 -0
- package/dist/resources/resource.js +23 -0
- package/dist/resources/tools.d.ts +24 -0
- package/dist/resources/tools.js +26 -0
- package/dist/resources/voices.d.ts +7 -9
- package/dist/resources/voices.js +7 -15
- package/dist/wait.d.ts +5 -3
- package/dist/wait.js +6 -4
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -8,15 +8,16 @@ export { type Client, type ClientOptions, createClient, DEFAULT_BASE_URL, } from
|
|
|
8
8
|
export { AuthenticationError, ConflictError, ConnectionError, InsufficientCreditsError, NotFoundError, PermissionError, PlatformError, type PlatformErrorCode, type PlatformErrorInit, RateLimitError, ServerError, TimeoutError, ValidationError, } from "./errors.js";
|
|
9
9
|
export type * from "./gen/index.js";
|
|
10
10
|
export type { Page } from "./paging.js";
|
|
11
|
-
export type { AgentKnowledge, AgentSettings, Agents, } from "./resources/agents.js";
|
|
11
|
+
export type { AgentKnowledge, AgentSettings, Agents, AgentTools, } from "./resources/agents.js";
|
|
12
12
|
export type { AssetListParams, Assets, AssetUploadFields, FolderListParams, Folders, } from "./resources/assets.js";
|
|
13
13
|
export type { EndUserCreated, EndUserExport, EndUserListParams, EndUsers, } from "./resources/end-users.js";
|
|
14
|
-
export type { EphemeralKeyCreateOptions, EphemeralKeyListParams, EphemeralKeys, } from "./resources/ephemeral-keys.js";
|
|
14
|
+
export type { EphemeralKeyCreateOptions, EphemeralKeyListParams, EphemeralKeyRevokeOptions, EphemeralKeys, } from "./resources/ephemeral-keys.js";
|
|
15
15
|
export type { GenerationListParams, Generations, Jobs, Skybox, } from "./resources/generations.js";
|
|
16
16
|
export type { Knowledge, KnowledgeInsightsParams, KnowledgeListParams, KnowledgeUploadFields, } from "./resources/knowledge.js";
|
|
17
|
-
export type { Resource, Waitable } from "./resources/resource.js";
|
|
17
|
+
export type { Library, Listing, Resource, Waitable, WaitableLibrary, } from "./resources/resource.js";
|
|
18
18
|
export type { Speech, Stt, SttEvent, SttParams, Transcript, Tts, } from "./resources/speech.js";
|
|
19
19
|
export type { TemplateFile, Templates } from "./resources/templates.js";
|
|
20
|
+
export type { Tools } from "./resources/tools.js";
|
|
20
21
|
export type { Usage, UsageParams } from "./resources/usage.js";
|
|
21
22
|
export type { Voices, VoiceUploadFields } from "./resources/voices.js";
|
|
22
23
|
export type { Fetch, RequestOptions } from "./transport.js";
|
|
@@ -6,15 +6,16 @@
|
|
|
6
6
|
* - **A save reaches running sessions within a minute**, not at once: an
|
|
7
7
|
* agent's version travels through the platform's `STANDING` copy.
|
|
8
8
|
* - **`settings`** are the organisation's, for every agent;
|
|
9
|
-
* **`knowledge.set`** replaces the entries one agent may look up
|
|
9
|
+
* **`knowledge.set`** replaces the entries one agent may look up, and
|
|
10
|
+
* **`tools.set`** the tools it can call.
|
|
10
11
|
* - **`create` is a 409 at the plan's maximum agents**; `delete` answers
|
|
11
12
|
* `true`, and `false` for one already gone.
|
|
12
13
|
* - **`list()` reads one page**: an organisation's agents are few, and the
|
|
13
14
|
* route answers them all with `next_cursor` `null` (`paging.ts`).
|
|
14
15
|
*/
|
|
15
|
-
import type { AgentCreateRequest, AgentInfo, AgentKnowledgeUpdate, AgentPage, AgentSettingsInfo, AgentSettingsUpdate, AgentSummary, AgentUpdate, KnowledgeAssigned, KnowledgeInfo } from "../gen/index.js";
|
|
16
|
+
import type { AgentCreateRequest, AgentInfo, AgentKnowledgeUpdate, AgentPage, AgentSettingsInfo, AgentSettingsUpdate, AgentSummary, AgentToolsUpdate, AgentUpdate, KnowledgeAssigned, KnowledgeInfo, ToolInfo, ToolsAssigned } from "../gen/index.js";
|
|
16
17
|
import type { RequestOptions, Transport } from "../transport.js";
|
|
17
|
-
import {
|
|
18
|
+
import { Library } from "./resource.js";
|
|
18
19
|
/** `agents.settings`: the organisation's, for every agent. */
|
|
19
20
|
export interface AgentSettings {
|
|
20
21
|
get(options?: RequestOptions): Promise<AgentSettingsInfo>;
|
|
@@ -27,13 +28,18 @@ export interface AgentKnowledge {
|
|
|
27
28
|
/** Replaces them all with these. */
|
|
28
29
|
set(agentId: string, body: AgentKnowledgeUpdate, options?: RequestOptions): Promise<KnowledgeAssigned>;
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
+
/** `agents.tools`: the tools one agent can call. */
|
|
32
|
+
export interface AgentTools {
|
|
33
|
+
/** Every tool it can call. */
|
|
34
|
+
list(agentId: string, options?: RequestOptions): AsyncGenerator<ToolInfo, void, undefined>;
|
|
35
|
+
/** Replaces them all with these, 20 at most. */
|
|
36
|
+
set(agentId: string, body: AgentToolsUpdate, options?: RequestOptions): Promise<ToolsAssigned>;
|
|
37
|
+
}
|
|
38
|
+
export declare class Agents extends Library<AgentInfo, AgentUpdate, AgentSummary, AgentPage, AgentCreateRequest> {
|
|
31
39
|
readonly settings: AgentSettings;
|
|
32
40
|
readonly knowledge: AgentKnowledge;
|
|
41
|
+
readonly tools: AgentTools;
|
|
33
42
|
constructor(api: Transport, base: string);
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
/** Every agent. */
|
|
37
|
-
list(options?: RequestOptions): AsyncGenerator<AgentSummary, void, undefined>;
|
|
38
|
-
create(body: AgentCreateRequest, options?: RequestOptions): Promise<AgentInfo>;
|
|
43
|
+
/** An agent's links to what the organisation has: its knowledge, its tools. */
|
|
44
|
+
protected links<T extends AgentKnowledge | AgentTools>(rest: string): T;
|
|
39
45
|
}
|
package/dist/resources/agents.js
CHANGED
|
@@ -6,34 +6,29 @@
|
|
|
6
6
|
* - **A save reaches running sessions within a minute**, not at once: an
|
|
7
7
|
* agent's version travels through the platform's `STANDING` copy.
|
|
8
8
|
* - **`settings`** are the organisation's, for every agent;
|
|
9
|
-
* **`knowledge.set`** replaces the entries one agent may look up
|
|
9
|
+
* **`knowledge.set`** replaces the entries one agent may look up, and
|
|
10
|
+
* **`tools.set`** the tools it can call.
|
|
10
11
|
* - **`create` is a 409 at the plan's maximum agents**; `delete` answers
|
|
11
12
|
* `true`, and `false` for one already gone.
|
|
12
13
|
* - **`list()` reads one page**: an organisation's agents are few, and the
|
|
13
14
|
* route answers them all with `next_cursor` `null` (`paging.ts`).
|
|
14
15
|
*/
|
|
15
|
-
import {
|
|
16
|
-
export class Agents extends
|
|
16
|
+
import { Library } from "./resource.js";
|
|
17
|
+
export class Agents extends Library {
|
|
17
18
|
constructor(api, base) {
|
|
18
19
|
super(api, base);
|
|
19
20
|
this.settings = {
|
|
20
21
|
get: (options) => this.send("GET", "/settings", options),
|
|
21
22
|
update: (body, options) => this.send("PUT", "/settings", options, body),
|
|
22
23
|
};
|
|
23
|
-
this.knowledge =
|
|
24
|
-
|
|
25
|
-
set: (id, body, options) => this.send("PUT", this.at(id, "/knowledge"), options, body),
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
/** The page of agents, as the route answers it. */
|
|
29
|
-
page(options) {
|
|
30
|
-
return this.send("GET", "", options);
|
|
24
|
+
this.knowledge = this.links("/knowledge");
|
|
25
|
+
this.tools = this.links("/tools");
|
|
31
26
|
}
|
|
32
|
-
/**
|
|
33
|
-
|
|
34
|
-
return
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
/** An agent's links to what the organisation has: its knowledge, its tools. */
|
|
28
|
+
links(rest) {
|
|
29
|
+
return {
|
|
30
|
+
list: (id, options) => this.each(this.at(id, rest), {}, options),
|
|
31
|
+
set: (id, body, options) => this.send("PUT", this.at(id, rest), options, body),
|
|
32
|
+
};
|
|
38
33
|
}
|
|
39
34
|
}
|
|
@@ -21,18 +21,15 @@
|
|
|
21
21
|
* and an API key cannot read them (`/v1/agent/*` takes only an ephemeral
|
|
22
22
|
* key): it mints a five-minute key for them, lists their sessions (200 a
|
|
23
23
|
* page), reads each transcript back to its start by `messages.next_cursor`
|
|
24
|
-
* (200 messages a page, four sessions at a time), reads their facts
|
|
25
|
-
* revokes the key in `finally` — after an abort or a failure
|
|
26
|
-
* cost: one mint (and `limits()` when cold) + ⌈S/200⌉ lists +
|
|
27
|
-
* transcript pages +
|
|
24
|
+
* (200 messages a page, four sessions at a time), reads their facts (200
|
|
25
|
+
* a page), and revokes the key in `finally` — after an abort or a failure
|
|
26
|
+
* too. The cost: one mint (and `limits()` when cold) + ⌈S/200⌉ lists +
|
|
27
|
+
* Σ⌈M/200⌉ transcript pages + ⌈F/200⌉ fact pages + one revoke. **Its ceilings**: the
|
|
28
28
|
* key is ordinary, so at the person's live-key cap or the plan's mint rate
|
|
29
29
|
* the export fails as the mint does (422, 429) and can be retried once a
|
|
30
30
|
* key lapses; it lives five minutes, so a history that takes longer to
|
|
31
31
|
* read fails with a 401; its one micro-credit is set aside like any key's,
|
|
32
|
-
* so an organisation with no balance cannot export (402)
|
|
33
|
-
* route answers the newest 100 in one page until it pages (left-overs
|
|
34
|
-
* #109) — read here by its cursor, so the day it does, the export has
|
|
35
|
-
* them all.
|
|
32
|
+
* so an organisation with no balance cannot export (402).
|
|
36
33
|
*/
|
|
37
34
|
import type { EndUserCreateRequest, EndUserDeleted, EndUserInfo, EndUserPage, EndUserUpdateRequest, FactInfo, ListEndUsersData, SessionDetail } from "../gen/index.js";
|
|
38
35
|
import { type RequestOptions, type Transport } from "../transport.js";
|
|
@@ -21,18 +21,15 @@
|
|
|
21
21
|
* and an API key cannot read them (`/v1/agent/*` takes only an ephemeral
|
|
22
22
|
* key): it mints a five-minute key for them, lists their sessions (200 a
|
|
23
23
|
* page), reads each transcript back to its start by `messages.next_cursor`
|
|
24
|
-
* (200 messages a page, four sessions at a time), reads their facts
|
|
25
|
-
* revokes the key in `finally` — after an abort or a failure
|
|
26
|
-
* cost: one mint (and `limits()` when cold) + ⌈S/200⌉ lists +
|
|
27
|
-
* transcript pages +
|
|
24
|
+
* (200 messages a page, four sessions at a time), reads their facts (200
|
|
25
|
+
* a page), and revokes the key in `finally` — after an abort or a failure
|
|
26
|
+
* too. The cost: one mint (and `limits()` when cold) + ⌈S/200⌉ lists +
|
|
27
|
+
* Σ⌈M/200⌉ transcript pages + ⌈F/200⌉ fact pages + one revoke. **Its ceilings**: the
|
|
28
28
|
* key is ordinary, so at the person's live-key cap or the plan's mint rate
|
|
29
29
|
* the export fails as the mint does (422, 429) and can be retried once a
|
|
30
30
|
* key lapses; it lives five minutes, so a history that takes longer to
|
|
31
31
|
* read fails with a 401; its one micro-credit is set aside like any key's,
|
|
32
|
-
* so an organisation with no balance cannot export (402)
|
|
33
|
-
* route answers the newest 100 in one page until it pages (left-overs
|
|
34
|
-
* #109) — read here by its cursor, so the day it does, the export has
|
|
35
|
-
* them all.
|
|
32
|
+
* so an organisation with no balance cannot export (402).
|
|
36
33
|
*/
|
|
37
34
|
import { pages } from "../paging.js";
|
|
38
35
|
import { segment, } from "../transport.js";
|
|
@@ -128,7 +125,7 @@ export class EndUsers extends Editable {
|
|
|
128
125
|
messages: { data: held.flat(), next_cursor: null },
|
|
129
126
|
};
|
|
130
127
|
});
|
|
131
|
-
const facts = await all(pages((cursor) => read("/v1/agent/facts", { cursor })));
|
|
128
|
+
const facts = await all(pages((cursor) => read("/v1/agent/facts", { limit: PAGE, cursor })));
|
|
132
129
|
return { end_user_id: key.end_user_id ?? id, sessions, facts };
|
|
133
130
|
}
|
|
134
131
|
finally {
|
|
@@ -5,24 +5,24 @@
|
|
|
5
5
|
* - **A key is prepaid**: its `credit_limit_micros` is set aside from the
|
|
6
6
|
* balance when it is minted (402 when it cannot be), and what it does not spend
|
|
7
7
|
* comes back when it settles.
|
|
8
|
-
* - **`create` clamps the lifetime by default** to the
|
|
9
|
-
*
|
|
10
|
-
* (`
|
|
11
|
-
*
|
|
12
|
-
* platform's can still be refused.
|
|
8
|
+
* - **`create` clamps the lifetime by default** to the tighter of the
|
|
9
|
+
* platform's maximum and the plan's for one end user's key, both read
|
|
10
|
+
* from `limits()` — which the API never does: past a cap is a 422
|
|
11
|
+
* (`apps/api/src/org/minting.ts`).
|
|
13
12
|
* - **`limits()` is cached five minutes per client**, so a mint is two
|
|
14
13
|
* requests cold and one warm. Concurrent cold callers share one read.
|
|
15
14
|
* - **`revoke` answers at once**, with the figures from before the key's
|
|
16
15
|
* end user DO settles: revocation leaves through the org DO's outbox
|
|
17
|
-
* (`apps/api/src/org/areas/keys.ts` `revokeEphemeral`).
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
16
|
+
* (`apps/api/src/org/areas/keys.ts` `revokeEphemeral`). With
|
|
17
|
+
* `{ settled: true }` it reads the key (`get`) until `settled_at` is set
|
|
18
|
+
* — seconds, longer while a memory job the key paid for runs — on the
|
|
19
|
+
* polls of `../wait.ts`; a `signal` is its deadline.
|
|
20
|
+
* - **`inspect` reads a key as itself** (`GET /v1/token` with that key):
|
|
21
|
+
* its spend as its end user DO counts it, turn by turn.
|
|
22
22
|
*/
|
|
23
23
|
import type { EphemeralKeyCreateRequest, EphemeralKeyCreateResponse, EphemeralKeyInfo, EphemeralKeyLimits, EphemeralKeyPage, EphemeralTokenSelf, ListEphemeralKeysData } from "../gen/index.js";
|
|
24
24
|
import { type RequestOptions } from "../transport.js";
|
|
25
|
-
import {
|
|
25
|
+
import { Readable } from "./resource.js";
|
|
26
26
|
export type EphemeralKeyListParams = NonNullable<ListEphemeralKeysData["query"]>;
|
|
27
27
|
export interface EphemeralKeyCreateOptions extends RequestOptions {
|
|
28
28
|
/**
|
|
@@ -32,12 +32,17 @@ export interface EphemeralKeyCreateOptions extends RequestOptions {
|
|
|
32
32
|
*/
|
|
33
33
|
clampTtl?: boolean;
|
|
34
34
|
}
|
|
35
|
-
export
|
|
35
|
+
export interface EphemeralKeyRevokeOptions extends RequestOptions {
|
|
36
|
+
/** Answer once the key's final figures are in (`settled_at` set), not at once. */
|
|
37
|
+
settled?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export declare class EphemeralKeys extends Readable<EphemeralKeyInfo> {
|
|
36
40
|
private cached;
|
|
37
41
|
/**
|
|
38
|
-
* What a key may be minted with: the
|
|
39
|
-
* largest credit limit,
|
|
40
|
-
*
|
|
42
|
+
* What a key may be minted with: the platform's longest lifetime and
|
|
43
|
+
* largest credit limit, the plan's for one end user's key (`plan_*`,
|
|
44
|
+
* `null` where it sets none), and the scopes this API key may grant.
|
|
45
|
+
* Cached five minutes per client.
|
|
41
46
|
*/
|
|
42
47
|
limits(options?: RequestOptions): Promise<EphemeralKeyLimits>;
|
|
43
48
|
/**
|
|
@@ -49,10 +54,11 @@ export declare class EphemeralKeys extends Resource {
|
|
|
49
54
|
create(body: EphemeralKeyCreateRequest, options?: EphemeralKeyCreateOptions): Promise<EphemeralKeyCreateResponse>;
|
|
50
55
|
/**
|
|
51
56
|
* Revokes a key: it is refused from now on, and what it did not spend
|
|
52
|
-
* comes back when it settles
|
|
53
|
-
* revoked, expired or unknown id answers
|
|
57
|
+
* comes back when it settles — awaited with `{ settled: true }`. `null`
|
|
58
|
+
* when there is no such key — a revoked, expired or unknown id answers
|
|
59
|
+
* as itself, a non-UUID as none.
|
|
54
60
|
*/
|
|
55
|
-
revoke(id: string, options?:
|
|
61
|
+
revoke(id: string, options?: EphemeralKeyRevokeOptions): Promise<EphemeralKeyInfo | null>;
|
|
56
62
|
/**
|
|
57
63
|
* A key as it reads itself: its scopes, limit, spend and expiry. `null`
|
|
58
64
|
* when the key is refused — expired, revoked, spent or not a key.
|
|
@@ -5,24 +5,25 @@
|
|
|
5
5
|
* - **A key is prepaid**: its `credit_limit_micros` is set aside from the
|
|
6
6
|
* balance when it is minted (402 when it cannot be), and what it does not spend
|
|
7
7
|
* comes back when it settles.
|
|
8
|
-
* - **`create` clamps the lifetime by default** to the
|
|
9
|
-
*
|
|
10
|
-
* (`
|
|
11
|
-
*
|
|
12
|
-
* platform's can still be refused.
|
|
8
|
+
* - **`create` clamps the lifetime by default** to the tighter of the
|
|
9
|
+
* platform's maximum and the plan's for one end user's key, both read
|
|
10
|
+
* from `limits()` — which the API never does: past a cap is a 422
|
|
11
|
+
* (`apps/api/src/org/minting.ts`).
|
|
13
12
|
* - **`limits()` is cached five minutes per client**, so a mint is two
|
|
14
13
|
* requests cold and one warm. Concurrent cold callers share one read.
|
|
15
14
|
* - **`revoke` answers at once**, with the figures from before the key's
|
|
16
15
|
* end user DO settles: revocation leaves through the org DO's outbox
|
|
17
|
-
* (`apps/api/src/org/areas/keys.ts` `revokeEphemeral`).
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
16
|
+
* (`apps/api/src/org/areas/keys.ts` `revokeEphemeral`). With
|
|
17
|
+
* `{ settled: true }` it reads the key (`get`) until `settled_at` is set
|
|
18
|
+
* — seconds, longer while a memory job the key paid for runs — on the
|
|
19
|
+
* polls of `../wait.ts`; a `signal` is its deadline.
|
|
20
|
+
* - **`inspect` reads a key as itself** (`GET /v1/token` with that key):
|
|
21
|
+
* its spend as its end user DO counts it, turn by turn.
|
|
22
22
|
*/
|
|
23
23
|
import { AuthenticationError } from "../errors.js";
|
|
24
24
|
import { orNull } from "../transport.js";
|
|
25
|
-
import {
|
|
25
|
+
import { poll } from "../wait.js";
|
|
26
|
+
import { Readable } from "./resource.js";
|
|
26
27
|
const LIMITS_TTL_MS = 5 * 60_000;
|
|
27
28
|
/** The route's largest page. */
|
|
28
29
|
const PAGE = 200;
|
|
@@ -44,12 +45,13 @@ function until(promise, signal) {
|
|
|
44
45
|
});
|
|
45
46
|
});
|
|
46
47
|
}
|
|
47
|
-
export class EphemeralKeys extends
|
|
48
|
+
export class EphemeralKeys extends Readable {
|
|
48
49
|
cached = null;
|
|
49
50
|
/**
|
|
50
|
-
* What a key may be minted with: the
|
|
51
|
-
* largest credit limit,
|
|
52
|
-
*
|
|
51
|
+
* What a key may be minted with: the platform's longest lifetime and
|
|
52
|
+
* largest credit limit, the plan's for one end user's key (`plan_*`,
|
|
53
|
+
* `null` where it sets none), and the scopes this API key may grant.
|
|
54
|
+
* Cached five minutes per client.
|
|
53
55
|
*/
|
|
54
56
|
limits(options = {}) {
|
|
55
57
|
const now = Date.now();
|
|
@@ -82,18 +84,23 @@ export class EphemeralKeys extends Resource {
|
|
|
82
84
|
const wanted = body.expires_in_seconds ?? limits.default_ttl_seconds;
|
|
83
85
|
sent = {
|
|
84
86
|
...body,
|
|
85
|
-
expires_in_seconds: Math.min(wanted, limits.max_ttl_seconds),
|
|
87
|
+
expires_in_seconds: Math.min(wanted, limits.max_ttl_seconds, limits.plan_max_ttl_seconds ?? wanted),
|
|
86
88
|
};
|
|
87
89
|
}
|
|
88
90
|
return this.send("POST", "", request, sent);
|
|
89
91
|
}
|
|
90
92
|
/**
|
|
91
93
|
* Revokes a key: it is refused from now on, and what it did not spend
|
|
92
|
-
* comes back when it settles
|
|
93
|
-
* revoked, expired or unknown id answers
|
|
94
|
+
* comes back when it settles — awaited with `{ settled: true }`. `null`
|
|
95
|
+
* when there is no such key — a revoked, expired or unknown id answers
|
|
96
|
+
* as itself, a non-UUID as none.
|
|
94
97
|
*/
|
|
95
|
-
revoke(id, options) {
|
|
96
|
-
|
|
98
|
+
async revoke(id, options = {}) {
|
|
99
|
+
const { settled, ...request } = options;
|
|
100
|
+
const key = await orNull(this.send("DELETE", this.at(id), request));
|
|
101
|
+
return key && settled
|
|
102
|
+
? poll(() => this.get(id, request), request, key, (k) => !k.settled_at)
|
|
103
|
+
: key;
|
|
97
104
|
}
|
|
98
105
|
/**
|
|
99
106
|
* A key as it reads itself: its scopes, limit, spend and expiry. `null`
|
|
@@ -40,3 +40,17 @@ export declare class Waitable<Item extends Job & {
|
|
|
40
40
|
/** `item` as made, or as it ended when `options.wait` says to wait. */
|
|
41
41
|
protected settled(item: Item, options: UploadOptions): Promise<Item>;
|
|
42
42
|
}
|
|
43
|
+
/** What a `Library` adds to its base. */
|
|
44
|
+
export interface Listing<Listed, ListPage, Create, Created> {
|
|
45
|
+
/** The page, as the route answers it: all of them, `next_cursor` `null`. */
|
|
46
|
+
page(options?: RequestOptions): Promise<ListPage>;
|
|
47
|
+
/** Every one of them. */
|
|
48
|
+
list(options?: RequestOptions): AsyncGenerator<Listed, void, undefined>;
|
|
49
|
+
create(body: Create, options?: RequestOptions): Promise<Created>;
|
|
50
|
+
}
|
|
51
|
+
/** An editable listed whole and made by a `POST`: the agents, the tools. */
|
|
52
|
+
export declare const Library: new <Item, Update, Listed, ListPage, Create, Created = Item>(api: Transport, base: string) => Editable<Item, Update> & Listing<Listed, ListPage, Create, Created>;
|
|
53
|
+
/** A waitable listed whole and made by a `POST`: the voices. */
|
|
54
|
+
export declare const WaitableLibrary: new <Item extends Job & {
|
|
55
|
+
id: string;
|
|
56
|
+
}, Update, Listed, ListPage, Create>(api: Transport, base: string) => Waitable<Item, Update> & Listing<Listed, ListPage, Create, Item>;
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
* `false` when there is nothing by that id — already done. One that
|
|
14
14
|
* reports what went with it (an end user's, a folder's) answers those
|
|
15
15
|
* counts, and `null` for nothing by that id: the same rule, with a body.
|
|
16
|
+
* - **`Library`** and **`WaitableLibrary`**: one of the two, listed whole
|
|
17
|
+
* in one page and made by a `POST` to the list — `page()`, `list()`,
|
|
18
|
+
* `create(body)`, written once (`listed`).
|
|
16
19
|
* - **`Waitable`**: an editable whose items are jobs — a voice, an asset,
|
|
17
20
|
* a knowledge entry — with `wait(id)` and `settled`, which an upload
|
|
18
21
|
* answers through.
|
|
@@ -83,3 +86,23 @@ export class Waitable extends Editable {
|
|
|
83
86
|
: item;
|
|
84
87
|
}
|
|
85
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* `Listing`'s three methods on `Base`, written once for every resource
|
|
91
|
+
* listed whole in one page and made by a `POST` to the list: a mixin, as
|
|
92
|
+
* the agents and the tools are editables and the voices waitables.
|
|
93
|
+
*/
|
|
94
|
+
const listed = (Base) => class extends Base {
|
|
95
|
+
page(options) {
|
|
96
|
+
return this.send("GET", "", options);
|
|
97
|
+
}
|
|
98
|
+
list(options) {
|
|
99
|
+
return this.each("", {}, options);
|
|
100
|
+
}
|
|
101
|
+
create(body, options) {
|
|
102
|
+
return this.send("POST", "", options, body);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
/** An editable listed whole and made by a `POST`: the agents, the tools. */
|
|
106
|
+
export const Library = listed(Editable);
|
|
107
|
+
/** A waitable listed whole and made by a `POST`: the voices. */
|
|
108
|
+
export const WaitableLibrary = listed(Waitable);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `client.tools`: what an organisation's agents can call while they reply
|
|
3
|
+
* — `/v1/tools*`. A tool is your server (`webhook`), sent a signed `POST`
|
|
4
|
+
* with the call, or the person's app (`app`), called over the agent's
|
|
5
|
+
* socket; each is turned on per agent (`agents.tools.set`), 20 at most.
|
|
6
|
+
*
|
|
7
|
+
* - **`create(body)`** answers a webhook's signing secret once, as does
|
|
8
|
+
* `rotateSecret` (`secret`); every call carries `X-Tool-Signature`.
|
|
9
|
+
* - **`test(id, { arguments })`** sends your server one call, signed as a
|
|
10
|
+
* real one, and answers what came back.
|
|
11
|
+
* - **`list()` reads one page**: a library holds 200 tools at most.
|
|
12
|
+
* - **`update` with `expected_version`** refuses an edit made over
|
|
13
|
+
* somebody else's (409); `delete` answers `true`, and `false` for one
|
|
14
|
+
* already gone.
|
|
15
|
+
*/
|
|
16
|
+
import type { ToolCreate, ToolInfo, ToolPage, ToolTestRequest, ToolTestResult, ToolUpdate, ToolWithSecret } from "../gen/index.js";
|
|
17
|
+
import type { RequestOptions } from "../transport.js";
|
|
18
|
+
import { Library } from "./resource.js";
|
|
19
|
+
export declare class Tools extends Library<ToolInfo, ToolUpdate, ToolInfo, ToolPage, ToolCreate, ToolWithSecret> {
|
|
20
|
+
/** A new signing secret, shown this once. */
|
|
21
|
+
rotateSecret(id: string, options?: RequestOptions): Promise<ToolWithSecret>;
|
|
22
|
+
/** One call to your server, as a conversation would send it: `{ arguments }`. */
|
|
23
|
+
test(id: string, body?: ToolTestRequest, options?: RequestOptions): Promise<ToolTestResult>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `client.tools`: what an organisation's agents can call while they reply
|
|
3
|
+
* — `/v1/tools*`. A tool is your server (`webhook`), sent a signed `POST`
|
|
4
|
+
* with the call, or the person's app (`app`), called over the agent's
|
|
5
|
+
* socket; each is turned on per agent (`agents.tools.set`), 20 at most.
|
|
6
|
+
*
|
|
7
|
+
* - **`create(body)`** answers a webhook's signing secret once, as does
|
|
8
|
+
* `rotateSecret` (`secret`); every call carries `X-Tool-Signature`.
|
|
9
|
+
* - **`test(id, { arguments })`** sends your server one call, signed as a
|
|
10
|
+
* real one, and answers what came back.
|
|
11
|
+
* - **`list()` reads one page**: a library holds 200 tools at most.
|
|
12
|
+
* - **`update` with `expected_version`** refuses an edit made over
|
|
13
|
+
* somebody else's (409); `delete` answers `true`, and `false` for one
|
|
14
|
+
* already gone.
|
|
15
|
+
*/
|
|
16
|
+
import { Library } from "./resource.js";
|
|
17
|
+
export class Tools extends Library {
|
|
18
|
+
/** A new signing secret, shown this once. */
|
|
19
|
+
rotateSecret(id, options) {
|
|
20
|
+
return this.send("POST", this.at(id, "/secret"), options);
|
|
21
|
+
}
|
|
22
|
+
/** One call to your server, as a conversation would send it: `{ arguments }`. */
|
|
23
|
+
test(id, body = {}, options) {
|
|
24
|
+
return this.send("POST", this.at(id, "/test"), options, body);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -16,20 +16,18 @@
|
|
|
16
16
|
import type { VoiceDesignRequest, VoiceDesignResult, VoiceDesignSaveRequest, VoiceDetail, VoiceInfo, VoiceInfoPage, VoiceUpdate, VoiceUpload, VoiceUploadRequest, VoiceUploadTicket } from "../gen/index.js";
|
|
17
17
|
import type { RequestOptions } from "../transport.js";
|
|
18
18
|
import { type UploadData, type UploadOptions } from "../upload.js";
|
|
19
|
-
import {
|
|
19
|
+
import { WaitableLibrary } from "./resource.js";
|
|
20
20
|
/** A recording's voice: the create's fields, and the recording's type. */
|
|
21
21
|
export type VoiceUploadFields = Omit<VoiceUpload, "upload_id"> & {
|
|
22
22
|
/** A Blob's own type by default: `audio/wav`, `audio/mpeg`, … */
|
|
23
23
|
content_type?: string;
|
|
24
24
|
};
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
/** Clones a recording already `PUT` to its ticket: `pending` at once. */
|
|
32
|
-
create(body: VoiceUpload, options?: RequestOptions): Promise<VoiceDetail>;
|
|
25
|
+
/**
|
|
26
|
+
* `update` renames a voice, or changes its description or defaults;
|
|
27
|
+
* `list()` is every voice this organisation may speak with; `create(body)`
|
|
28
|
+
* clones a recording already `PUT` to its ticket, `pending` at once.
|
|
29
|
+
*/
|
|
30
|
+
export declare class Voices extends WaitableLibrary<VoiceDetail, VoiceUpdate, VoiceInfo, VoiceInfoPage, VoiceUpload> {
|
|
33
31
|
/** A signed URL to `PUT` a recording to, with exactly this type. */
|
|
34
32
|
uploadUrl(body: VoiceUploadRequest, options?: RequestOptions): Promise<VoiceUploadTicket>;
|
|
35
33
|
/** Uploads a recording and clones it: `uploadUrl`, the `PUT`, `create`. */
|
package/dist/resources/voices.js
CHANGED
|
@@ -14,21 +14,13 @@
|
|
|
14
14
|
* - **`list()` reads one page**: the route answers every voice in it.
|
|
15
15
|
*/
|
|
16
16
|
import { needType, put, } from "../upload.js";
|
|
17
|
-
import {
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/** Every voice this organisation may speak with. */
|
|
25
|
-
list(options) {
|
|
26
|
-
return this.each("", {}, options);
|
|
27
|
-
}
|
|
28
|
-
/** Clones a recording already `PUT` to its ticket: `pending` at once. */
|
|
29
|
-
create(body, options) {
|
|
30
|
-
return this.send("POST", "", options, body);
|
|
31
|
-
}
|
|
17
|
+
import { WaitableLibrary } from "./resource.js";
|
|
18
|
+
/**
|
|
19
|
+
* `update` renames a voice, or changes its description or defaults;
|
|
20
|
+
* `list()` is every voice this organisation may speak with; `create(body)`
|
|
21
|
+
* clones a recording already `PUT` to its ticket, `pending` at once.
|
|
22
|
+
*/
|
|
23
|
+
export class Voices extends WaitableLibrary {
|
|
32
24
|
/** A signed URL to `PUT` a recording to, with exactly this type. */
|
|
33
25
|
uploadUrl(body, options) {
|
|
34
26
|
return this.send("POST", "/upload-url", options, body);
|
package/dist/wait.d.ts
CHANGED
|
@@ -32,7 +32,9 @@ export interface Job {
|
|
|
32
32
|
status: string;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* Reads `read` until its status is final
|
|
36
|
-
*
|
|
35
|
+
* Reads `read` until its status is final — or until `pending` says it no
|
|
36
|
+
* longer is, for what is not a job (a revoked key's settlement) —
|
|
37
|
+
* starting from `first` (a job just made, so the first read waits) or
|
|
38
|
+
* with a read now.
|
|
37
39
|
*/
|
|
38
|
-
export declare function poll<T
|
|
40
|
+
export declare function poll<T>(read: () => Promise<T>, options?: RequestOptions, first?: T, pending?: (job: T) => boolean): Promise<T>;
|
package/dist/wait.js
CHANGED
|
@@ -37,12 +37,14 @@ const IN_PROGRESS = [
|
|
|
37
37
|
const FIRST_MS = 1_000;
|
|
38
38
|
const MAX_MS = 10_000;
|
|
39
39
|
/**
|
|
40
|
-
* Reads `read` until its status is final
|
|
41
|
-
*
|
|
40
|
+
* Reads `read` until its status is final — or until `pending` says it no
|
|
41
|
+
* longer is, for what is not a job (a revoked key's settlement) —
|
|
42
|
+
* starting from `first` (a job just made, so the first read waits) or
|
|
43
|
+
* with a read now.
|
|
42
44
|
*/
|
|
43
|
-
export async function poll(read, options = {}, first) {
|
|
45
|
+
export async function poll(read, options = {}, first, pending = (job) => IN_PROGRESS.includes(job.status)) {
|
|
44
46
|
let job = first ?? (await read());
|
|
45
|
-
for (let ms = FIRST_MS;
|
|
47
|
+
for (let ms = FIRST_MS; pending(job);) {
|
|
46
48
|
await sleep(ms, options.signal);
|
|
47
49
|
job = await read();
|
|
48
50
|
ms = Math.min(ms * 1.5, MAX_MS);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lumavox/server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "The Lumavox API from your server: end users, ephemeral keys and the rest, typed from the published OpenAPI document. Zero dependencies.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|