@spekoai/sdk 0.0.1

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 ADDED
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@spekoai/sdk` will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SpekoAI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # @spekoai/sdk
2
+
3
+ Official TypeScript SDK for [Speko](https://speko.ai) — one API, every voice provider.
4
+
5
+ Speko is a voice AI gateway that benchmarks every STT, LLM, and TTS provider
6
+ across languages and verticals, then routes each request to the best provider
7
+ in real time. Failover is handled. You write one integration; Speko picks the
8
+ right provider for every call.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @spekoai/sdk
14
+ # or
15
+ pnpm add @spekoai/sdk
16
+ # or
17
+ bun add @spekoai/sdk
18
+ ```
19
+
20
+ ## Quickstart
21
+
22
+ ```ts
23
+ import { Speko } from '@spekoai/sdk';
24
+ import { readFile } from 'node:fs/promises';
25
+
26
+ const speko = new Speko({ apiKey: process.env.SPEKO_API_KEY });
27
+
28
+ // Transcribe — best STT provider auto-routed for your language + vertical
29
+ const audio = await readFile('./call.wav');
30
+ const { text, provider, confidence } = await speko.transcribe(audio, {
31
+ language: 'es-MX',
32
+ vertical: 'healthcare',
33
+ });
34
+
35
+ // Synthesize — best TTS provider auto-routed
36
+ const speech = await speko.synthesize('Hello world', {
37
+ language: 'en',
38
+ vertical: 'general',
39
+ });
40
+
41
+ // Complete — best LLM provider auto-routed
42
+ const { text: reply } = await speko.complete({
43
+ messages: [{ role: 'user', content: 'Hi!' }],
44
+ intent: { language: 'en', vertical: 'general' },
45
+ });
46
+ ```
47
+
48
+ ## Documentation
49
+
50
+ Full API reference and guides: <https://docs.speko.ai>
51
+
52
+ ## Contributing
53
+
54
+ See [CONTRIBUTING.md](./CONTRIBUTING.md).
55
+
56
+ ## License
57
+
58
+ [MIT](./LICENSE)
@@ -0,0 +1,4 @@
1
+ export { Speko } from './lib/client.js';
2
+ export { SpekoApiError, SpekoAuthError, SpekoRateLimitError } from './lib/errors.js';
3
+ export type { SpekoClientOptions, PipelineConfig, CreateSessionParams, Session, SessionDetail, UsageSummary, UsageByProvider, UsageQueryParams, Vertical, OptimizeFor, RoutingIntent, TranscribeOptions, TranscribeResult, SynthesizeOptions, SynthesizeResult, ChatMessage, CompleteParams, CompleteResult, } from './lib/types/index.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACrF,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,OAAO,EACP,aAAa,EACb,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,cAAc,GACf,MAAM,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { Speko } from './lib/client.js';
2
+ export { SpekoApiError, SpekoAuthError, SpekoRateLimitError } from './lib/errors.js';
@@ -0,0 +1,47 @@
1
+ import type { CompleteParams, CompleteResult, SpekoClientOptions, SynthesizeOptions, SynthesizeResult, TranscribeOptions, TranscribeResult } from './types/index.js';
2
+ import { Sessions } from './resources/sessions.js';
3
+ import { Usage } from './resources/usage.js';
4
+ /**
5
+ * Speko client — one API, every voice provider.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { Speko } from '@spekoai/sdk';
10
+ *
11
+ * const speko = new Speko({ apiKey: process.env.SPEKO_API_KEY });
12
+ *
13
+ * const { text, provider } = await speko.transcribe(audioBytes, {
14
+ * language: 'es-MX',
15
+ * vertical: 'healthcare',
16
+ * });
17
+ * ```
18
+ */
19
+ export declare class Speko {
20
+ /** Real-time voice sessions over LiveKit (back-compat path). */
21
+ readonly sessions: Sessions;
22
+ readonly usage: Usage;
23
+ private readonly transcribeResource;
24
+ private readonly synthesizeResource;
25
+ private readonly completeResource;
26
+ constructor(options: SpekoClientOptions);
27
+ /**
28
+ * Transcribe audio. The router picks the best STT provider for your
29
+ * `(language, vertical, optimizeFor)` and fails over automatically.
30
+ *
31
+ * Pass an `AbortSignal` to cancel the in-flight request — useful when a
32
+ * calling framework (e.g. LiveKit Agents) tears down a session mid-call.
33
+ */
34
+ transcribe(audio: Uint8Array, options: TranscribeOptions, abortSignal?: AbortSignal): Promise<TranscribeResult>;
35
+ /**
36
+ * Synthesize text into audio. The router picks the best TTS provider and
37
+ * fails over automatically. The result includes the audio bytes plus the
38
+ * provider's native content type.
39
+ */
40
+ synthesize(text: string, options: SynthesizeOptions, abortSignal?: AbortSignal): Promise<SynthesizeResult>;
41
+ /**
42
+ * Run an LLM completion. The router picks the best LLM provider and fails
43
+ * over automatically.
44
+ */
45
+ complete(params: CompleteParams, abortSignal?: AbortSignal): Promise<CompleteResult>;
46
+ }
47
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAQ7C;;;;;;;;;;;;;;GAcG;AACH,qBAAa,KAAK;IAChB,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAEtB,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAa;IAChD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAa;IAChD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAW;gBAEhC,OAAO,EAAE,kBAAkB;IAoBvC;;;;;;OAMG;IACH,UAAU,CACR,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,gBAAgB,CAAC;IAI5B;;;;OAIG;IACH,UAAU,CACR,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,gBAAgB,CAAC;IAI5B;;;OAGG;IACH,QAAQ,CACN,MAAM,EAAE,cAAc,EACtB,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,cAAc,CAAC;CAG3B"}
@@ -0,0 +1,71 @@
1
+ import { HttpClient } from './http.js';
2
+ import { Sessions } from './resources/sessions.js';
3
+ import { Usage } from './resources/usage.js';
4
+ import { Transcribe } from './resources/transcribe.js';
5
+ import { Synthesize } from './resources/synthesize.js';
6
+ import { Complete } from './resources/complete.js';
7
+ const DEFAULT_BASE_URL = 'https://api.speko.ai';
8
+ const DEFAULT_TIMEOUT = 30_000;
9
+ /**
10
+ * Speko client — one API, every voice provider.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { Speko } from '@spekoai/sdk';
15
+ *
16
+ * const speko = new Speko({ apiKey: process.env.SPEKO_API_KEY });
17
+ *
18
+ * const { text, provider } = await speko.transcribe(audioBytes, {
19
+ * language: 'es-MX',
20
+ * vertical: 'healthcare',
21
+ * });
22
+ * ```
23
+ */
24
+ export class Speko {
25
+ /** Real-time voice sessions over LiveKit (back-compat path). */
26
+ sessions;
27
+ usage;
28
+ transcribeResource;
29
+ synthesizeResource;
30
+ completeResource;
31
+ constructor(options) {
32
+ if (!options.apiKey) {
33
+ throw new Error('Speko: apiKey is required. Get one at https://dashboard.speko.ai/api-keys');
34
+ }
35
+ const http = new HttpClient({
36
+ baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
37
+ apiKey: options.apiKey,
38
+ timeout: options.timeout ?? DEFAULT_TIMEOUT,
39
+ });
40
+ this.sessions = new Sessions(http);
41
+ this.usage = new Usage(http);
42
+ this.transcribeResource = new Transcribe(http);
43
+ this.synthesizeResource = new Synthesize(http);
44
+ this.completeResource = new Complete(http);
45
+ }
46
+ /**
47
+ * Transcribe audio. The router picks the best STT provider for your
48
+ * `(language, vertical, optimizeFor)` and fails over automatically.
49
+ *
50
+ * Pass an `AbortSignal` to cancel the in-flight request — useful when a
51
+ * calling framework (e.g. LiveKit Agents) tears down a session mid-call.
52
+ */
53
+ transcribe(audio, options, abortSignal) {
54
+ return this.transcribeResource.call(audio, options, abortSignal);
55
+ }
56
+ /**
57
+ * Synthesize text into audio. The router picks the best TTS provider and
58
+ * fails over automatically. The result includes the audio bytes plus the
59
+ * provider's native content type.
60
+ */
61
+ synthesize(text, options, abortSignal) {
62
+ return this.synthesizeResource.call(text, options, abortSignal);
63
+ }
64
+ /**
65
+ * Run an LLM completion. The router picks the best LLM provider and fails
66
+ * over automatically.
67
+ */
68
+ complete(params, abortSignal) {
69
+ return this.completeResource.call(params, abortSignal);
70
+ }
71
+ }
@@ -0,0 +1,13 @@
1
+ export declare class SpekoApiError extends Error {
2
+ readonly status: number;
3
+ readonly code: string;
4
+ constructor(message: string, status: number, code: string);
5
+ }
6
+ export declare class SpekoAuthError extends SpekoApiError {
7
+ constructor(message?: string);
8
+ }
9
+ export declare class SpekoRateLimitError extends SpekoApiError {
10
+ readonly retryAfter: number | null;
11
+ constructor(message?: string, retryAfter?: number | null);
12
+ }
13
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAM1D;AAED,qBAAa,cAAe,SAAQ,aAAa;gBACnC,OAAO,SAA+B;CAInD;AAED,qBAAa,mBAAoB,SAAQ,aAAa;IACpD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;gBAEvB,OAAO,SAAwB,EAAE,UAAU,GAAE,MAAM,GAAG,IAAW;CAK9E"}
@@ -0,0 +1,24 @@
1
+ export class SpekoApiError extends Error {
2
+ status;
3
+ code;
4
+ constructor(message, status, code) {
5
+ super(message);
6
+ this.name = 'SpekoApiError';
7
+ this.status = status;
8
+ this.code = code;
9
+ }
10
+ }
11
+ export class SpekoAuthError extends SpekoApiError {
12
+ constructor(message = 'Invalid or missing API key') {
13
+ super(message, 401, 'AUTH_ERROR');
14
+ this.name = 'SpekoAuthError';
15
+ }
16
+ }
17
+ export class SpekoRateLimitError extends SpekoApiError {
18
+ retryAfter;
19
+ constructor(message = 'Rate limit exceeded', retryAfter = null) {
20
+ super(message, 429, 'RATE_LIMITED');
21
+ this.name = 'SpekoRateLimitError';
22
+ this.retryAfter = retryAfter;
23
+ }
24
+ }
@@ -0,0 +1,38 @@
1
+ export interface HttpClientOptions {
2
+ baseUrl: string;
3
+ apiKey: string;
4
+ timeout: number;
5
+ }
6
+ export declare class HttpClient {
7
+ private readonly baseUrl;
8
+ private readonly authHeader;
9
+ private readonly jsonHeaders;
10
+ private readonly timeout;
11
+ constructor(options: HttpClientOptions);
12
+ request<T>(method: string, path: string, body?: unknown, externalSignal?: AbortSignal): Promise<T>;
13
+ get<T>(path: string, externalSignal?: AbortSignal): Promise<T>;
14
+ post<T>(path: string, body: unknown, externalSignal?: AbortSignal): Promise<T>;
15
+ delete<T>(path: string, externalSignal?: AbortSignal): Promise<T>;
16
+ /**
17
+ * Send raw bytes as the request body and parse a JSON response.
18
+ * Used by `speko.transcribe()` to upload audio and receive a transcript.
19
+ */
20
+ requestRaw<T>(method: string, path: string, bodyBytes: Uint8Array, extraHeaders: Record<string, string>, externalSignal?: AbortSignal): Promise<T>;
21
+ /**
22
+ * Send JSON and receive a binary response (e.g. synthesized audio).
23
+ * Returns the raw bytes plus the response headers so callers can read
24
+ * `Content-Type`, `X-Speko-Provider`, etc.
25
+ */
26
+ requestBinary(method: string, path: string, body: unknown, externalSignal?: AbortSignal): Promise<{
27
+ bytes: Uint8Array;
28
+ headers: Record<string, string>;
29
+ }>;
30
+ /**
31
+ * Compose the internal timeout signal with an optional external signal so
32
+ * that callers can cancel in-flight requests (e.g. LiveKit Agents tearing
33
+ * down a session) while still enforcing the client's configured timeout.
34
+ */
35
+ private buildSignal;
36
+ private handleError;
37
+ }
38
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAID,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyB;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,EAAE,iBAAiB;IAWhC,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,cAAc,CAAC,EAAE,WAAW,GAC3B,OAAO,CAAC,CAAC,CAAC;IAsBP,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAI9D,IAAI,CAAC,CAAC,EACV,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,EACb,cAAc,CAAC,EAAE,WAAW,GAC3B,OAAO,CAAC,CAAC,CAAC;IAIP,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAIvE;;;OAGG;IACG,UAAU,CAAC,CAAC,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,UAAU,EACrB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,cAAc,CAAC,EAAE,WAAW,GAC3B,OAAO,CAAC,CAAC,CAAC;IA4Bb;;;;OAIG;IACG,aAAa,CACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,EACb,cAAc,CAAC,EAAE,WAAW,GAC3B,OAAO,CAAC;QAAE,KAAK,EAAE,UAAU,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;IA4BlE;;;;OAIG;IACH,OAAO,CAAC,WAAW;YA6BL,WAAW;CA4B1B"}
@@ -0,0 +1,154 @@
1
+ import { SpekoApiError, SpekoAuthError, SpekoRateLimitError } from './errors.js';
2
+ const USER_AGENT = '@spekoai/sdk/0.0.1';
3
+ export class HttpClient {
4
+ baseUrl;
5
+ authHeader;
6
+ jsonHeaders;
7
+ timeout;
8
+ constructor(options) {
9
+ this.baseUrl = options.baseUrl.replace(/\/$/, '');
10
+ this.authHeader = `Bearer ${options.apiKey}`;
11
+ this.jsonHeaders = {
12
+ Authorization: this.authHeader,
13
+ 'Content-Type': 'application/json',
14
+ 'User-Agent': USER_AGENT,
15
+ };
16
+ this.timeout = options.timeout;
17
+ }
18
+ async request(method, path, body, externalSignal) {
19
+ const url = `${this.baseUrl}${path}`;
20
+ const { signal, cleanup } = this.buildSignal(externalSignal);
21
+ try {
22
+ const response = await fetch(url, {
23
+ method,
24
+ headers: this.jsonHeaders,
25
+ body: body ? JSON.stringify(body) : undefined,
26
+ signal,
27
+ });
28
+ if (!response.ok) {
29
+ await this.handleError(response);
30
+ }
31
+ return (await response.json());
32
+ }
33
+ finally {
34
+ cleanup();
35
+ }
36
+ }
37
+ async get(path, externalSignal) {
38
+ return this.request('GET', path, undefined, externalSignal);
39
+ }
40
+ async post(path, body, externalSignal) {
41
+ return this.request('POST', path, body, externalSignal);
42
+ }
43
+ async delete(path, externalSignal) {
44
+ return this.request('DELETE', path, undefined, externalSignal);
45
+ }
46
+ /**
47
+ * Send raw bytes as the request body and parse a JSON response.
48
+ * Used by `speko.transcribe()` to upload audio and receive a transcript.
49
+ */
50
+ async requestRaw(method, path, bodyBytes, extraHeaders, externalSignal) {
51
+ const url = `${this.baseUrl}${path}`;
52
+ const { signal, cleanup } = this.buildSignal(externalSignal);
53
+ try {
54
+ const headers = {
55
+ Authorization: this.authHeader,
56
+ 'User-Agent': USER_AGENT,
57
+ ...extraHeaders,
58
+ };
59
+ const response = await fetch(url, {
60
+ method,
61
+ headers,
62
+ body: bodyBytes,
63
+ signal,
64
+ });
65
+ if (!response.ok) {
66
+ await this.handleError(response);
67
+ }
68
+ return (await response.json());
69
+ }
70
+ finally {
71
+ cleanup();
72
+ }
73
+ }
74
+ /**
75
+ * Send JSON and receive a binary response (e.g. synthesized audio).
76
+ * Returns the raw bytes plus the response headers so callers can read
77
+ * `Content-Type`, `X-Speko-Provider`, etc.
78
+ */
79
+ async requestBinary(method, path, body, externalSignal) {
80
+ const url = `${this.baseUrl}${path}`;
81
+ const { signal, cleanup } = this.buildSignal(externalSignal);
82
+ try {
83
+ const response = await fetch(url, {
84
+ method,
85
+ headers: this.jsonHeaders,
86
+ body: body ? JSON.stringify(body) : undefined,
87
+ signal,
88
+ });
89
+ if (!response.ok) {
90
+ await this.handleError(response);
91
+ }
92
+ const buffer = await response.arrayBuffer();
93
+ const headers = {};
94
+ response.headers.forEach((value, key) => {
95
+ headers[key] = value;
96
+ });
97
+ return { bytes: new Uint8Array(buffer), headers };
98
+ }
99
+ finally {
100
+ cleanup();
101
+ }
102
+ }
103
+ /**
104
+ * Compose the internal timeout signal with an optional external signal so
105
+ * that callers can cancel in-flight requests (e.g. LiveKit Agents tearing
106
+ * down a session) while still enforcing the client's configured timeout.
107
+ */
108
+ buildSignal(externalSignal) {
109
+ const controller = new AbortController();
110
+ const timer = setTimeout(() => controller.abort(), this.timeout);
111
+ if (externalSignal) {
112
+ if (externalSignal.aborted) {
113
+ controller.abort(externalSignal.reason);
114
+ }
115
+ else {
116
+ const onAbort = () => controller.abort(externalSignal.reason);
117
+ externalSignal.addEventListener('abort', onAbort, { once: true });
118
+ return {
119
+ signal: controller.signal,
120
+ cleanup: () => {
121
+ clearTimeout(timer);
122
+ externalSignal.removeEventListener('abort', onAbort);
123
+ },
124
+ };
125
+ }
126
+ }
127
+ return {
128
+ signal: controller.signal,
129
+ cleanup: () => clearTimeout(timer),
130
+ };
131
+ }
132
+ async handleError(response) {
133
+ const text = await response.text();
134
+ let message;
135
+ let code;
136
+ try {
137
+ const json = JSON.parse(text);
138
+ message = json.error ?? text;
139
+ code = json.code ?? 'UNKNOWN';
140
+ }
141
+ catch {
142
+ message = text || response.statusText;
143
+ code = 'UNKNOWN';
144
+ }
145
+ if (response.status === 401) {
146
+ throw new SpekoAuthError(message);
147
+ }
148
+ if (response.status === 429) {
149
+ const retryAfter = response.headers.get('Retry-After');
150
+ throw new SpekoRateLimitError(message, retryAfter ? parseInt(retryAfter, 10) : null);
151
+ }
152
+ throw new SpekoApiError(message, response.status, code);
153
+ }
154
+ }
@@ -0,0 +1,20 @@
1
+ import type { HttpClient } from '../http.js';
2
+ import type { CompleteParams, CompleteResult } from '../types/index.js';
3
+ export declare class Complete {
4
+ private readonly http;
5
+ constructor(http: HttpClient);
6
+ /**
7
+ * Run an LLM completion. The Speko router picks the best provider for your
8
+ * `(language, vertical, optimizeFor)` and falls over automatically.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const { text, provider } = await speko.complete({
13
+ * messages: [{ role: 'user', content: 'Hi!' }],
14
+ * intent: { language: 'en', vertical: 'general' },
15
+ * });
16
+ * ```
17
+ */
18
+ call(params: CompleteParams, abortSignal?: AbortSignal): Promise<CompleteResult>;
19
+ }
20
+ //# sourceMappingURL=complete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/complete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExE,qBAAa,QAAQ;IACP,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;;;;;;;;OAWG;IACG,IAAI,CACR,MAAM,EAAE,cAAc,EACtB,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,cAAc,CAAC;CAG3B"}
@@ -0,0 +1,21 @@
1
+ export class Complete {
2
+ http;
3
+ constructor(http) {
4
+ this.http = http;
5
+ }
6
+ /**
7
+ * Run an LLM completion. The Speko router picks the best provider for your
8
+ * `(language, vertical, optimizeFor)` and falls over automatically.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const { text, provider } = await speko.complete({
13
+ * messages: [{ role: 'user', content: 'Hi!' }],
14
+ * intent: { language: 'en', vertical: 'general' },
15
+ * });
16
+ * ```
17
+ */
18
+ async call(params, abortSignal) {
19
+ return this.http.post('/v1/complete', params, abortSignal);
20
+ }
21
+ }
@@ -0,0 +1,44 @@
1
+ import type { HttpClient } from '../http.js';
2
+ import type { CreateSessionParams, Session, SessionDetail } from '../types/index.js';
3
+ export declare class Sessions {
4
+ private readonly http;
5
+ constructor(http: HttpClient);
6
+ /**
7
+ * Create a new voice session.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const session = await speko.sessions.create({
12
+ * pipeline: {
13
+ * stt: { provider: 'deepgram' },
14
+ * llm: { provider: 'openai', model: 'gpt-4o' },
15
+ * tts: { provider: 'elevenlabs', voice: 'rachel' },
16
+ * },
17
+ * });
18
+ * console.log(session.token); // Use to connect via LiveKit
19
+ * ```
20
+ */
21
+ create(params: CreateSessionParams): Promise<Session>;
22
+ /**
23
+ * Get a session by ID.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const session = await speko.sessions.get('sess_abc123');
28
+ * ```
29
+ */
30
+ get(sessionId: string): Promise<SessionDetail>;
31
+ /**
32
+ * End an active session.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * await speko.sessions.end('sess_abc123');
37
+ * ```
38
+ */
39
+ end(sessionId: string): Promise<{
40
+ id: string;
41
+ status: string;
42
+ }>;
43
+ }
44
+ //# sourceMappingURL=sessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EACV,mBAAmB,EACnB,OAAO,EACP,aAAa,EACd,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,QAAQ;IACP,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;;;;;;;;;;;OAcG;IACG,MAAM,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IAI3D;;;;;;;OAOG;IACG,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAIpD;;;;;;;OAOG;IACG,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAKtE"}
@@ -0,0 +1,46 @@
1
+ export class Sessions {
2
+ http;
3
+ constructor(http) {
4
+ this.http = http;
5
+ }
6
+ /**
7
+ * Create a new voice session.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const session = await speko.sessions.create({
12
+ * pipeline: {
13
+ * stt: { provider: 'deepgram' },
14
+ * llm: { provider: 'openai', model: 'gpt-4o' },
15
+ * tts: { provider: 'elevenlabs', voice: 'rachel' },
16
+ * },
17
+ * });
18
+ * console.log(session.token); // Use to connect via LiveKit
19
+ * ```
20
+ */
21
+ async create(params) {
22
+ return this.http.post('/v1/sessions', params);
23
+ }
24
+ /**
25
+ * Get a session by ID.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * const session = await speko.sessions.get('sess_abc123');
30
+ * ```
31
+ */
32
+ async get(sessionId) {
33
+ return this.http.get(`/v1/sessions/${sessionId}`);
34
+ }
35
+ /**
36
+ * End an active session.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * await speko.sessions.end('sess_abc123');
41
+ * ```
42
+ */
43
+ async end(sessionId) {
44
+ return this.http.delete(`/v1/sessions/${sessionId}`);
45
+ }
46
+ }
@@ -0,0 +1,25 @@
1
+ import type { HttpClient } from '../http.js';
2
+ import type { SynthesizeOptions, SynthesizeResult } from '../types/index.js';
3
+ export declare class Synthesize {
4
+ private readonly http;
5
+ constructor(http: HttpClient);
6
+ /**
7
+ * Synthesize text into audio. The Speko router picks the best TTS provider
8
+ * for your `(language, vertical, optimizeFor)` and falls over automatically.
9
+ *
10
+ * The returned audio's format depends on the chosen provider — check the
11
+ * `contentType` field on the result. ElevenLabs returns `audio/mpeg`,
12
+ * Cartesia returns raw `audio/pcm;rate=24000`.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const result = await speko.synthesize('Hello world', {
17
+ * language: 'en',
18
+ * vertical: 'general',
19
+ * });
20
+ * await writeFile(`out.${result.contentType.includes('mpeg') ? 'mp3' : 'pcm'}`, result.audio);
21
+ * ```
22
+ */
23
+ call(text: string, options: SynthesizeOptions, abortSignal?: AbortSignal): Promise<SynthesizeResult>;
24
+ }
25
+ //# sourceMappingURL=synthesize.d.ts.map
@@ -0,0 +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,EACjB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;;;;;;;;;;;;;OAgBG;IACG,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,gBAAgB,CAAC;CA2B7B"}
@@ -0,0 +1,44 @@
1
+ export class Synthesize {
2
+ http;
3
+ constructor(http) {
4
+ this.http = http;
5
+ }
6
+ /**
7
+ * Synthesize text into audio. The Speko router picks the best TTS provider
8
+ * for your `(language, vertical, optimizeFor)` and falls over automatically.
9
+ *
10
+ * The returned audio's format depends on the chosen provider — check the
11
+ * `contentType` field on the result. ElevenLabs returns `audio/mpeg`,
12
+ * Cartesia returns raw `audio/pcm;rate=24000`.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const result = await speko.synthesize('Hello world', {
17
+ * language: 'en',
18
+ * vertical: 'general',
19
+ * });
20
+ * await writeFile(`out.${result.contentType.includes('mpeg') ? 'mp3' : 'pcm'}`, result.audio);
21
+ * ```
22
+ */
23
+ async call(text, options, abortSignal) {
24
+ const intent = {
25
+ language: options.language,
26
+ vertical: options.vertical,
27
+ ...(options.optimizeFor !== undefined && { optimizeFor: options.optimizeFor }),
28
+ };
29
+ const body = { text, intent };
30
+ if (options.voice !== undefined)
31
+ body['voice'] = options.voice;
32
+ if (options.speed !== undefined)
33
+ body['speed'] = options.speed;
34
+ const { bytes, headers } = await this.http.requestBinary('POST', '/v1/synthesize', body, abortSignal);
35
+ return {
36
+ audio: bytes,
37
+ contentType: headers['content-type'] ?? 'application/octet-stream',
38
+ provider: headers['x-speko-provider'] ?? 'unknown',
39
+ model: headers['x-speko-model'] ?? 'unknown',
40
+ failoverCount: parseInt(headers['x-speko-failover-count'] ?? '0', 10),
41
+ scoresRunId: headers['x-speko-scores-run-id'] || null,
42
+ };
43
+ }
44
+ }
@@ -0,0 +1,21 @@
1
+ import type { HttpClient } from '../http.js';
2
+ import type { TranscribeOptions, TranscribeResult } from '../types/index.js';
3
+ export declare class Transcribe {
4
+ private readonly http;
5
+ constructor(http: HttpClient);
6
+ /**
7
+ * Transcribe audio. The Speko router picks the best STT provider for
8
+ * your `(language, vertical, optimizeFor)` and falls over automatically.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const audio = await readFile('./call.wav');
13
+ * const { text, provider, confidence } = await speko.transcribe(audio, {
14
+ * language: 'es-MX',
15
+ * vertical: 'healthcare',
16
+ * });
17
+ * ```
18
+ */
19
+ call(audio: Uint8Array, options: TranscribeOptions, abortSignal?: AbortSignal): Promise<TranscribeResult>;
20
+ }
21
+ //# sourceMappingURL=transcribe.d.ts.map
@@ -0,0 +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,EACjB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;;;;;;;;;OAYG;IACG,IAAI,CACR,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,gBAAgB,CAAC;CAkB7B"}
@@ -0,0 +1,30 @@
1
+ export class Transcribe {
2
+ http;
3
+ constructor(http) {
4
+ this.http = http;
5
+ }
6
+ /**
7
+ * Transcribe audio. The Speko router picks the best STT provider for
8
+ * your `(language, vertical, optimizeFor)` and falls over automatically.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const audio = await readFile('./call.wav');
13
+ * const { text, provider, confidence } = await speko.transcribe(audio, {
14
+ * language: 'es-MX',
15
+ * vertical: 'healthcare',
16
+ * });
17
+ * ```
18
+ */
19
+ async call(audio, options, abortSignal) {
20
+ const intent = {
21
+ language: options.language,
22
+ vertical: options.vertical,
23
+ ...(options.optimizeFor !== undefined && { optimizeFor: options.optimizeFor }),
24
+ };
25
+ return this.http.requestRaw('POST', '/v1/transcribe', audio, {
26
+ 'Content-Type': options.contentType ?? 'audio/wav',
27
+ 'X-Speko-Intent': JSON.stringify(intent),
28
+ }, abortSignal);
29
+ }
30
+ }
@@ -0,0 +1,17 @@
1
+ import type { HttpClient } from '../http.js';
2
+ import type { UsageSummary, UsageQueryParams } from '../types/index.js';
3
+ export declare class Usage {
4
+ private readonly http;
5
+ constructor(http: HttpClient);
6
+ /**
7
+ * Get usage summary for the current billing period.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const usage = await speko.usage.get();
12
+ * console.log(usage.totalMinutes, usage.totalCost);
13
+ * ```
14
+ */
15
+ get(params?: UsageQueryParams): Promise<UsageSummary>;
16
+ }
17
+ //# sourceMappingURL=usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../../src/lib/resources/usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAExE,qBAAa,KAAK;IACJ,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C;;;;;;;;OAQG;IACG,GAAG,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;CAU5D"}
@@ -0,0 +1,24 @@
1
+ export class Usage {
2
+ http;
3
+ constructor(http) {
4
+ this.http = http;
5
+ }
6
+ /**
7
+ * Get usage summary for the current billing period.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const usage = await speko.usage.get();
12
+ * console.log(usage.totalMinutes, usage.totalCost);
13
+ * ```
14
+ */
15
+ async get(params) {
16
+ const query = new URLSearchParams();
17
+ if (params?.from)
18
+ query.set('from', params.from);
19
+ if (params?.to)
20
+ query.set('to', params.to);
21
+ const qs = query.toString();
22
+ return this.http.get(`/v1/usage${qs ? `?${qs}` : ''}`);
23
+ }
24
+ }
@@ -0,0 +1,139 @@
1
+ /** Options for creating a Speko client. */
2
+ export interface SpekoClientOptions {
3
+ /** API key for authentication. */
4
+ apiKey: string;
5
+ /** Base URL of the Speko API. Defaults to https://api.speko.ai */
6
+ baseUrl?: string;
7
+ /** Request timeout in milliseconds. Defaults to 30000. */
8
+ timeout?: number;
9
+ }
10
+ /** Pipeline configuration for a voice session. */
11
+ export interface PipelineConfig {
12
+ stt: {
13
+ provider: string;
14
+ model?: string;
15
+ language?: string;
16
+ keywords?: string[];
17
+ };
18
+ llm: {
19
+ provider: string;
20
+ model: string;
21
+ systemPrompt?: string;
22
+ temperature?: number;
23
+ maxTokens?: number;
24
+ };
25
+ tts: {
26
+ provider: string;
27
+ voice: string;
28
+ model?: string;
29
+ speed?: number;
30
+ };
31
+ }
32
+ /** Parameters for creating a session. */
33
+ export interface CreateSessionParams {
34
+ pipeline: PipelineConfig;
35
+ metadata?: Record<string, unknown>;
36
+ }
37
+ /** A voice session returned by the API. */
38
+ export interface Session {
39
+ id: string;
40
+ status: 'created' | 'connecting' | 'active' | 'ended' | 'failed';
41
+ roomName: string;
42
+ token: string;
43
+ livekitUrl: string;
44
+ createdAt: string;
45
+ }
46
+ /** A session detail object. */
47
+ export interface SessionDetail {
48
+ id: string;
49
+ workspaceId: string;
50
+ status: 'created' | 'connecting' | 'active' | 'ended' | 'failed';
51
+ roomName: string;
52
+ pipelineConfig: PipelineConfig;
53
+ metadata: Record<string, unknown>;
54
+ createdAt: string;
55
+ updatedAt: string;
56
+ endedAt: string | null;
57
+ }
58
+ /** Usage record for a workspace. */
59
+ export interface UsageSummary {
60
+ totalSessions: number;
61
+ totalMinutes: number;
62
+ totalCost: number;
63
+ breakdown: UsageByProvider[];
64
+ }
65
+ export interface UsageByProvider {
66
+ provider: string;
67
+ type: 'stt' | 'llm' | 'tts';
68
+ metric: string;
69
+ quantity: number;
70
+ cost: number;
71
+ }
72
+ /** Parameters for querying usage. */
73
+ export interface UsageQueryParams {
74
+ /** Start date (ISO 8601). */
75
+ from?: string;
76
+ /** End date (ISO 8601). */
77
+ to?: string;
78
+ }
79
+ /** Vertical labels supported by the router. */
80
+ export type Vertical = 'general' | 'healthcare' | 'finance' | 'legal';
81
+ /** Optimization preset that biases the router's weighted score. */
82
+ export type OptimizeFor = 'balanced' | 'accuracy' | 'latency' | 'cost';
83
+ /** Routing intent passed to the proxy primitives. */
84
+ export interface RoutingIntent {
85
+ /** BCP-47 language tag, e.g. "en" or "es-MX". */
86
+ language: string;
87
+ vertical: Vertical;
88
+ optimizeFor?: OptimizeFor;
89
+ }
90
+ export interface TranscribeOptions extends RoutingIntent {
91
+ /** MIME type of the audio body. Defaults to "audio/wav". */
92
+ contentType?: string;
93
+ }
94
+ export interface TranscribeResult {
95
+ text: string;
96
+ provider: string;
97
+ model: string;
98
+ confidence: number | null;
99
+ failoverCount: number;
100
+ scoresRunId: string | null;
101
+ }
102
+ export interface SynthesizeOptions extends RoutingIntent {
103
+ /** Optional voice override. Otherwise the SDK uses each provider's default. */
104
+ voice?: string;
105
+ speed?: number;
106
+ }
107
+ export interface SynthesizeResult {
108
+ /** Raw audio bytes. Format depends on the chosen provider — see `contentType`. */
109
+ audio: Uint8Array;
110
+ /** MIME type of the audio (e.g. "audio/mpeg" for ElevenLabs, "audio/pcm;rate=24000" for Cartesia). */
111
+ contentType: string;
112
+ provider: string;
113
+ model: string;
114
+ failoverCount: number;
115
+ scoresRunId: string | null;
116
+ }
117
+ export interface ChatMessage {
118
+ role: 'system' | 'user' | 'assistant';
119
+ content: string;
120
+ }
121
+ export interface CompleteParams {
122
+ messages: ChatMessage[];
123
+ intent: RoutingIntent;
124
+ systemPrompt?: string;
125
+ temperature?: number;
126
+ maxTokens?: number;
127
+ }
128
+ export interface CompleteResult {
129
+ text: string;
130
+ provider: string;
131
+ model: string;
132
+ usage: {
133
+ promptTokens: number;
134
+ completionTokens: number;
135
+ };
136
+ failoverCount: number;
137
+ scoresRunId: string | null;
138
+ }
139
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/types/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@spekoai/sdk",
3
+ "version": "0.0.1",
4
+ "description": "Official Speko TypeScript SDK — one API, every voice provider",
5
+ "license": "MIT",
6
+ "author": "Speko",
7
+ "homepage": "https://github.com/SpekoAI/typescript-sdk#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/SpekoAI/typescript-sdk.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/SpekoAI/typescript-sdk/issues"
14
+ },
15
+ "keywords": [
16
+ "speko",
17
+ "voice-ai",
18
+ "stt",
19
+ "tts",
20
+ "llm",
21
+ "sdk",
22
+ "typescript"
23
+ ],
24
+ "type": "module",
25
+ "main": "./dist/index.js",
26
+ "module": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "sideEffects": false,
29
+ "files": [
30
+ "dist",
31
+ "README.md",
32
+ "LICENSE",
33
+ "CHANGELOG.md"
34
+ ],
35
+ "exports": {
36
+ "./package.json": "./package.json",
37
+ ".": {
38
+ "@spekoai/source": "./src/index.ts",
39
+ "types": "./dist/index.d.ts",
40
+ "import": "./dist/index.js",
41
+ "default": "./dist/index.js"
42
+ }
43
+ },
44
+ "publishConfig": {
45
+ "access": "public",
46
+ "registry": "https://registry.npmjs.org/",
47
+ "provenance": true
48
+ },
49
+ "dependencies": {
50
+ "tslib": "^2.3.0"
51
+ }
52
+ }