@spekoai/sdk 0.3.0 → 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/CHANGELOG.md +13 -0
- package/README.md +3 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/client.d.ts +8 -1
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/client.js +15 -0
- package/dist/lib/http.d.ts +14 -0
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js +166 -0
- package/dist/lib/resources/agents.d.ts +68 -0
- package/dist/lib/resources/agents.d.ts.map +1 -0
- package/dist/lib/resources/agents.js +90 -0
- package/dist/lib/resources/complete.d.ts +2 -1
- package/dist/lib/resources/complete.d.ts.map +1 -1
- package/dist/lib/resources/complete.js +27 -1
- package/dist/lib/resources/credits.d.ts +1 -2
- package/dist/lib/resources/credits.d.ts.map +1 -1
- package/dist/lib/resources/credits.js +1 -2
- package/dist/lib/resources/knowledge-bases.d.ts +60 -0
- package/dist/lib/resources/knowledge-bases.d.ts.map +1 -0
- package/dist/lib/resources/knowledge-bases.js +138 -0
- package/dist/lib/resources/synthesize.d.ts +2 -1
- package/dist/lib/resources/synthesize.d.ts.map +1 -1
- package/dist/lib/resources/synthesize.js +31 -3
- package/dist/lib/resources/transcribe.d.ts +2 -1
- package/dist/lib/resources/transcribe.d.ts.map +1 -1
- package/dist/lib/resources/transcribe.js +32 -1
- package/dist/lib/types/index.d.ts +299 -4
- package/dist/lib/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { HttpClient } from '../http.js';
|
|
2
|
+
import type { KnowledgeBaseCreateParams, KnowledgeBaseDocumentCreateParams, KnowledgeBaseDocumentCreateResult, KnowledgeBaseDocumentPollOptions, KnowledgeBaseDocumentRow, KnowledgeBaseDocumentUploadParams, KnowledgeBaseListParams, KnowledgeBaseRow } from '../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Per-agent knowledge bases. Each KB owns documents that get embedded
|
|
5
|
+
* into a Chroma collection so the agent can retrieve relevant chunks
|
|
6
|
+
* during a call. Every agent created via {@link Agents.create}
|
|
7
|
+
* auto-provisions a `Default` KB; additional KBs can be created
|
|
8
|
+
* explicitly with {@link KnowledgeBases.create}.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const kb = await speko.knowledgeBases.create({
|
|
13
|
+
* agentId: agent.id,
|
|
14
|
+
* name: 'Product FAQ',
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* const doc = await speko.knowledgeBases.uploadDocument(kb.id, {
|
|
18
|
+
* filename: 'faq.md',
|
|
19
|
+
* contentType: 'text/markdown',
|
|
20
|
+
* data: await Bun.file('faq.md').arrayBuffer(),
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* const ready = await speko.knowledgeBases.pollDocumentReady(kb.id, doc.id);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare class KnowledgeBases {
|
|
27
|
+
private readonly http;
|
|
28
|
+
constructor(http: HttpClient);
|
|
29
|
+
create(params: KnowledgeBaseCreateParams): Promise<KnowledgeBaseRow>;
|
|
30
|
+
list(params?: KnowledgeBaseListParams): Promise<KnowledgeBaseRow[]>;
|
|
31
|
+
get(kbId: string): Promise<KnowledgeBaseRow>;
|
|
32
|
+
delete(kbId: string): Promise<{
|
|
33
|
+
deleted: boolean;
|
|
34
|
+
}>;
|
|
35
|
+
listDocuments(kbId: string): Promise<KnowledgeBaseDocumentRow[]>;
|
|
36
|
+
getDocument(kbId: string, docId: string): Promise<KnowledgeBaseDocumentRow>;
|
|
37
|
+
createDocument(kbId: string, params: KnowledgeBaseDocumentCreateParams): Promise<KnowledgeBaseDocumentCreateResult>;
|
|
38
|
+
finalizeDocument(kbId: string, docId: string): Promise<KnowledgeBaseDocumentRow>;
|
|
39
|
+
deleteDocument(kbId: string, docId: string): Promise<{
|
|
40
|
+
deleted: boolean;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Convenience wrapper: register a document, upload its bytes to the
|
|
44
|
+
* signed PUT URL the server mints, then call finalize. Returns the
|
|
45
|
+
* document with status flipped to `processing`. Call
|
|
46
|
+
* {@link pollDocumentReady} to wait for ingest completion.
|
|
47
|
+
*
|
|
48
|
+
* The server's signed upload URL expires 600 seconds after issuance,
|
|
49
|
+
* so do not hold the result of {@link createDocument} for long before
|
|
50
|
+
* uploading. This wrapper performs all three steps back-to-back.
|
|
51
|
+
*/
|
|
52
|
+
uploadDocument(kbId: string, params: KnowledgeBaseDocumentUploadParams): Promise<KnowledgeBaseDocumentRow>;
|
|
53
|
+
/**
|
|
54
|
+
* Poll a document until it reaches `ready` or `failed` status, or the
|
|
55
|
+
* timeout elapses. Throws {@link SpekoApiError} on `failed` (with the
|
|
56
|
+
* server's `errorMessage`) or on timeout.
|
|
57
|
+
*/
|
|
58
|
+
pollDocumentReady(kbId: string, docId: string, opts?: KnowledgeBaseDocumentPollOptions): Promise<KnowledgeBaseDocumentRow>;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=knowledge-bases.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-bases.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/knowledge-bases.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,KAAK,EACV,yBAAyB,EACzB,iCAAiC,EACjC,iCAAiC,EACjC,gCAAgC,EAChC,wBAAwB,EACxB,iCAAiC,EACjC,uBAAuB,EACvB,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAK3B;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,MAAM,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIpE,IAAI,CAAC,MAAM,GAAE,uBAA4B,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IASvE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAM5C,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAMnD,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,EAAE,CAAC;IAMhE,WAAW,CACT,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,wBAAwB,CAAC;IAMpC,cAAc,CACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,iCAAiC,GACxC,OAAO,CAAC,iCAAiC,CAAC;IAO7C,gBAAgB,CACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,wBAAwB,CAAC;IAOpC,cAAc,CACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAMhC;;;;;;;;;OASG;IACG,cAAc,CAClB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,iCAAiC,GACxC,OAAO,CAAC,wBAAwB,CAAC;IA4BpC;;;;OAIG;IACG,iBAAiB,CACrB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,gCAAqC,GAC1C,OAAO,CAAC,wBAAwB,CAAC;CAwBrC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { SpekoApiError } from '../errors.js';
|
|
2
|
+
const DEFAULT_POLL_INTERVAL_MS = 2_000;
|
|
3
|
+
const DEFAULT_POLL_TIMEOUT_MS = 120_000;
|
|
4
|
+
/**
|
|
5
|
+
* Per-agent knowledge bases. Each KB owns documents that get embedded
|
|
6
|
+
* into a Chroma collection so the agent can retrieve relevant chunks
|
|
7
|
+
* during a call. Every agent created via {@link Agents.create}
|
|
8
|
+
* auto-provisions a `Default` KB; additional KBs can be created
|
|
9
|
+
* explicitly with {@link KnowledgeBases.create}.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const kb = await speko.knowledgeBases.create({
|
|
14
|
+
* agentId: agent.id,
|
|
15
|
+
* name: 'Product FAQ',
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* const doc = await speko.knowledgeBases.uploadDocument(kb.id, {
|
|
19
|
+
* filename: 'faq.md',
|
|
20
|
+
* contentType: 'text/markdown',
|
|
21
|
+
* data: await Bun.file('faq.md').arrayBuffer(),
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* const ready = await speko.knowledgeBases.pollDocumentReady(kb.id, doc.id);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export class KnowledgeBases {
|
|
28
|
+
http;
|
|
29
|
+
constructor(http) {
|
|
30
|
+
this.http = http;
|
|
31
|
+
}
|
|
32
|
+
create(params) {
|
|
33
|
+
return this.http.post('/v1/knowledge-bases', params);
|
|
34
|
+
}
|
|
35
|
+
list(params = {}) {
|
|
36
|
+
const query = new URLSearchParams();
|
|
37
|
+
if (params.agentId)
|
|
38
|
+
query.set('agentId', params.agentId);
|
|
39
|
+
const qs = query.toString();
|
|
40
|
+
return this.http.get(`/v1/knowledge-bases${qs ? `?${qs}` : ''}`);
|
|
41
|
+
}
|
|
42
|
+
get(kbId) {
|
|
43
|
+
return this.http.get(`/v1/knowledge-bases/${encodeURIComponent(kbId)}`);
|
|
44
|
+
}
|
|
45
|
+
delete(kbId) {
|
|
46
|
+
return this.http.delete(`/v1/knowledge-bases/${encodeURIComponent(kbId)}`);
|
|
47
|
+
}
|
|
48
|
+
listDocuments(kbId) {
|
|
49
|
+
return this.http.get(`/v1/knowledge-bases/${encodeURIComponent(kbId)}/documents`);
|
|
50
|
+
}
|
|
51
|
+
getDocument(kbId, docId) {
|
|
52
|
+
return this.http.get(`/v1/knowledge-bases/${encodeURIComponent(kbId)}/documents/${encodeURIComponent(docId)}`);
|
|
53
|
+
}
|
|
54
|
+
createDocument(kbId, params) {
|
|
55
|
+
return this.http.post(`/v1/knowledge-bases/${encodeURIComponent(kbId)}/documents`, params);
|
|
56
|
+
}
|
|
57
|
+
finalizeDocument(kbId, docId) {
|
|
58
|
+
return this.http.post(`/v1/knowledge-bases/${encodeURIComponent(kbId)}/documents/${encodeURIComponent(docId)}/finalize`, {});
|
|
59
|
+
}
|
|
60
|
+
deleteDocument(kbId, docId) {
|
|
61
|
+
return this.http.delete(`/v1/knowledge-bases/${encodeURIComponent(kbId)}/documents/${encodeURIComponent(docId)}`);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Convenience wrapper: register a document, upload its bytes to the
|
|
65
|
+
* signed PUT URL the server mints, then call finalize. Returns the
|
|
66
|
+
* document with status flipped to `processing`. Call
|
|
67
|
+
* {@link pollDocumentReady} to wait for ingest completion.
|
|
68
|
+
*
|
|
69
|
+
* The server's signed upload URL expires 600 seconds after issuance,
|
|
70
|
+
* so do not hold the result of {@link createDocument} for long before
|
|
71
|
+
* uploading. This wrapper performs all three steps back-to-back.
|
|
72
|
+
*/
|
|
73
|
+
async uploadDocument(kbId, params) {
|
|
74
|
+
const sizeBytes = byteLengthOf(params.data);
|
|
75
|
+
const { document, upload } = await this.createDocument(kbId, {
|
|
76
|
+
filename: params.filename,
|
|
77
|
+
contentType: params.contentType,
|
|
78
|
+
sizeBytes,
|
|
79
|
+
metadata: params.metadata,
|
|
80
|
+
});
|
|
81
|
+
const putResponse = await fetch(upload.url, {
|
|
82
|
+
method: upload.method,
|
|
83
|
+
headers: upload.headers,
|
|
84
|
+
body: toBodyInit(params.data),
|
|
85
|
+
});
|
|
86
|
+
if (!putResponse.ok) {
|
|
87
|
+
const text = await safeReadText(putResponse);
|
|
88
|
+
throw new SpekoApiError(`Document upload failed: ${putResponse.status} ${text || putResponse.statusText}`, putResponse.status, 'DOCUMENT_UPLOAD_FAILED');
|
|
89
|
+
}
|
|
90
|
+
return this.finalizeDocument(kbId, document.id);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Poll a document until it reaches `ready` or `failed` status, or the
|
|
94
|
+
* timeout elapses. Throws {@link SpekoApiError} on `failed` (with the
|
|
95
|
+
* server's `errorMessage`) or on timeout.
|
|
96
|
+
*/
|
|
97
|
+
async pollDocumentReady(kbId, docId, opts = {}) {
|
|
98
|
+
const intervalMs = opts.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
99
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_POLL_TIMEOUT_MS;
|
|
100
|
+
const deadline = Date.now() + timeoutMs;
|
|
101
|
+
while (Date.now() < deadline) {
|
|
102
|
+
const doc = await this.getDocument(kbId, docId);
|
|
103
|
+
if (doc.status === 'ready')
|
|
104
|
+
return doc;
|
|
105
|
+
if (doc.status === 'failed') {
|
|
106
|
+
throw new SpekoApiError(doc.errorMessage ?? 'Document ingest failed', 500, 'DOCUMENT_INGEST_FAILED');
|
|
107
|
+
}
|
|
108
|
+
await delay(intervalMs);
|
|
109
|
+
}
|
|
110
|
+
throw new SpekoApiError(`Document ingest timed out after ${timeoutMs}ms`, 408, 'DOCUMENT_INGEST_TIMEOUT');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function byteLengthOf(data) {
|
|
114
|
+
if (data instanceof Blob)
|
|
115
|
+
return data.size;
|
|
116
|
+
if (data instanceof Uint8Array)
|
|
117
|
+
return data.byteLength;
|
|
118
|
+
return data.byteLength;
|
|
119
|
+
}
|
|
120
|
+
function toBodyInit(data) {
|
|
121
|
+
if (data instanceof Blob)
|
|
122
|
+
return data;
|
|
123
|
+
if (data instanceof Uint8Array) {
|
|
124
|
+
return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
|
|
125
|
+
}
|
|
126
|
+
return data;
|
|
127
|
+
}
|
|
128
|
+
async function safeReadText(r) {
|
|
129
|
+
try {
|
|
130
|
+
return await r.text();
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return '';
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function delay(ms) {
|
|
137
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
138
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HttpClient } from '../http.js';
|
|
2
|
-
import type { SynthesizeOptions, SynthesizeResult } from '../types/index.js';
|
|
2
|
+
import type { SynthesizeOptions, SynthesizeResult, SynthesizeStreamResult } from '../types/index.js';
|
|
3
3
|
export declare class Synthesize {
|
|
4
4
|
private readonly http;
|
|
5
5
|
constructor(http: HttpClient);
|
|
@@ -20,5 +20,6 @@ export declare class Synthesize {
|
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
22
|
call(text: string, options: SynthesizeOptions, abortSignal?: AbortSignal): Promise<SynthesizeResult>;
|
|
23
|
+
stream(text: string, options: SynthesizeOptions, abortSignal?: AbortSignal): Promise<SynthesizeStreamResult>;
|
|
23
24
|
}
|
|
24
25
|
//# sourceMappingURL=synthesize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synthesize.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/synthesize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"synthesize.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/synthesize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;;;;;;;;;;;;OAeG;IACG,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,gBAAgB,CAAC;IAiBtB,MAAM,CACV,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,sBAAsB,CAAC;CAgCnC"}
|
|
@@ -20,6 +20,21 @@ export class Synthesize {
|
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
22
|
async call(text, options, abortSignal) {
|
|
23
|
+
const streamed = await this.stream(text, options, abortSignal);
|
|
24
|
+
const chunks = [];
|
|
25
|
+
for await (const chunk of streamed) {
|
|
26
|
+
chunks.push(chunk);
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
audio: concatChunks(chunks),
|
|
30
|
+
contentType: streamed.contentType,
|
|
31
|
+
provider: streamed.provider,
|
|
32
|
+
model: streamed.model,
|
|
33
|
+
failoverCount: streamed.failoverCount,
|
|
34
|
+
scoresRunId: streamed.scoresRunId,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
async stream(text, options, abortSignal) {
|
|
23
38
|
const intent = {
|
|
24
39
|
language: options.language,
|
|
25
40
|
...(options.region !== undefined && { region: options.region }),
|
|
@@ -32,14 +47,27 @@ export class Synthesize {
|
|
|
32
47
|
body['speed'] = options.speed;
|
|
33
48
|
if (options.constraints !== undefined)
|
|
34
49
|
body['constraints'] = options.constraints;
|
|
35
|
-
const {
|
|
36
|
-
|
|
37
|
-
audio: bytes,
|
|
50
|
+
const { chunks, headers } = await this.http.requestBinaryStream('POST', '/v1/synthesize', body, abortSignal);
|
|
51
|
+
const result = {
|
|
38
52
|
contentType: headers['content-type'] ?? 'application/octet-stream',
|
|
39
53
|
provider: headers['x-speko-provider'] ?? 'unknown',
|
|
40
54
|
model: headers['x-speko-model'] ?? 'unknown',
|
|
41
55
|
failoverCount: parseInt(headers['x-speko-failover-count'] ?? '0', 10),
|
|
42
56
|
scoresRunId: headers['x-speko-scores-run-id'] || null,
|
|
57
|
+
[Symbol.asyncIterator]() {
|
|
58
|
+
return chunks;
|
|
59
|
+
},
|
|
43
60
|
};
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function concatChunks(chunks) {
|
|
65
|
+
const total = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);
|
|
66
|
+
const out = new Uint8Array(total);
|
|
67
|
+
let offset = 0;
|
|
68
|
+
for (const chunk of chunks) {
|
|
69
|
+
out.set(chunk, offset);
|
|
70
|
+
offset += chunk.byteLength;
|
|
44
71
|
}
|
|
72
|
+
return out;
|
|
45
73
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HttpClient } from '../http.js';
|
|
2
|
-
import type { TranscribeOptions, TranscribeResult } from '../types/index.js';
|
|
2
|
+
import type { TranscribeOptions, TranscribeResult, TranscribeStreamEvent } from '../types/index.js';
|
|
3
3
|
export declare class Transcribe {
|
|
4
4
|
private readonly http;
|
|
5
5
|
constructor(http: HttpClient);
|
|
@@ -16,5 +16,6 @@ export declare class Transcribe {
|
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
18
18
|
call(audio: Uint8Array, options: TranscribeOptions, abortSignal?: AbortSignal): Promise<TranscribeResult>;
|
|
19
|
+
stream(audio: Uint8Array, options: TranscribeOptions, abortSignal?: AbortSignal): AsyncIterableIterator<TranscribeStreamEvent>;
|
|
19
20
|
}
|
|
20
21
|
//# sourceMappingURL=transcribe.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcribe.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/transcribe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"transcribe.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/transcribe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAG3B,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;;;;;;;;OAWG;IACG,IAAI,CACR,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,gBAAgB,CAAC;IAsBrB,MAAM,CACX,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,qBAAqB,CAAC,qBAAqB,CAAC;CA+BhD"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SpekoApiError } from '../errors.js';
|
|
1
2
|
export class Transcribe {
|
|
2
3
|
http;
|
|
3
4
|
constructor(http) {
|
|
@@ -16,6 +17,28 @@ export class Transcribe {
|
|
|
16
17
|
* ```
|
|
17
18
|
*/
|
|
18
19
|
async call(audio, options, abortSignal) {
|
|
20
|
+
let done;
|
|
21
|
+
for await (const event of this.stream(audio, options, abortSignal)) {
|
|
22
|
+
if (event.type === 'done') {
|
|
23
|
+
done = {
|
|
24
|
+
text: event.text,
|
|
25
|
+
provider: event.provider,
|
|
26
|
+
model: event.model,
|
|
27
|
+
confidence: event.confidence,
|
|
28
|
+
failoverCount: event.failoverCount,
|
|
29
|
+
scoresRunId: event.scoresRunId,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
else if (event.type === 'error') {
|
|
33
|
+
throw new SpekoApiError(event.error, 200, event.code);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (!done) {
|
|
37
|
+
throw new SpekoApiError('Transcribe stream ended without a done event', 200, 'STREAM_ENDED');
|
|
38
|
+
}
|
|
39
|
+
return done;
|
|
40
|
+
}
|
|
41
|
+
async *stream(audio, options, abortSignal) {
|
|
19
42
|
const intent = {
|
|
20
43
|
language: options.language,
|
|
21
44
|
...(options.region !== undefined && { region: options.region }),
|
|
@@ -28,6 +51,14 @@ export class Transcribe {
|
|
|
28
51
|
if (options.constraints) {
|
|
29
52
|
headers['X-Speko-Constraints'] = JSON.stringify(options.constraints);
|
|
30
53
|
}
|
|
31
|
-
|
|
54
|
+
if (options.keywords && options.keywords.length > 0) {
|
|
55
|
+
headers['X-Speko-Stt-Options'] = JSON.stringify({
|
|
56
|
+
keywords: [...options.keywords],
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
const stream = await this.http.requestRawSse('POST', '/v1/transcribe', audio, headers, abortSignal);
|
|
60
|
+
for await (const event of stream) {
|
|
61
|
+
yield { ...event.data, type: event.event };
|
|
62
|
+
}
|
|
32
63
|
}
|
|
33
64
|
}
|