@tanstack/ai-elevenlabs 0.3.3 → 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.
|
@@ -8,13 +8,24 @@ import { ElevenLabsOutputFormat } from '../model-meta.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export interface ElevenLabsClientConfig {
|
|
10
10
|
apiKey?: string;
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Base URL for every request. Same option name as the other adapters, so a
|
|
13
|
+
* gateway config can be spread into any of them. Wins over `baseUrl` when
|
|
14
|
+
* both are set.
|
|
15
|
+
*/
|
|
16
|
+
baseURL?: string;
|
|
17
|
+
/** Alias of `baseURL`. */
|
|
12
18
|
baseUrl?: string;
|
|
13
19
|
/** Per-request timeout passed through to the SDK (ms). */
|
|
14
20
|
timeoutInSeconds?: number;
|
|
15
21
|
/** Override the number of SDK-level retries. */
|
|
16
22
|
maxRetries?: number;
|
|
17
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Headers sent with every request. Same option name as the other adapters.
|
|
25
|
+
* Wins over `headers` when both are set.
|
|
26
|
+
*/
|
|
27
|
+
defaultHeaders?: Record<string, string>;
|
|
28
|
+
/** Alias of `defaultHeaders`. */
|
|
18
29
|
headers?: Record<string, string>;
|
|
19
30
|
}
|
|
20
31
|
export declare function getElevenLabsApiKeyFromEnv(): string;
|
package/dist/esm/utils/client.js
CHANGED
|
@@ -23,12 +23,14 @@ function getElevenLabsAgentIdFromEnv() {
|
|
|
23
23
|
*/
|
|
24
24
|
function createElevenLabsClient(config) {
|
|
25
25
|
const apiKey = config?.apiKey ?? getElevenLabsApiKeyFromEnv();
|
|
26
|
+
const baseUrl = config?.baseURL ?? config?.baseUrl;
|
|
27
|
+
const headers = config?.defaultHeaders ?? config?.headers;
|
|
26
28
|
return new ElevenLabsClient({
|
|
27
29
|
apiKey,
|
|
28
|
-
...
|
|
30
|
+
...baseUrl ? { baseUrl } : {},
|
|
29
31
|
...config?.timeoutInSeconds != null ? { timeoutInSeconds: config.timeoutInSeconds } : {},
|
|
30
32
|
...config?.maxRetries != null ? { maxRetries: config.maxRetries } : {},
|
|
31
|
-
...
|
|
33
|
+
...headers ? { headers } : {}
|
|
32
34
|
});
|
|
33
35
|
}
|
|
34
36
|
var generateId$1 = generateId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":[],"sources":["../../../src/utils/client.ts"],"sourcesContent":["import { ElevenLabsClient } from '@elevenlabs/elevenlabs-js'\nimport {\n getApiKeyFromEnv,\n generateId as sharedGenerateId,\n} from '@tanstack/ai-utils'\nimport type { ElevenLabsOutputFormat } from '../model-meta'\n\n/**\n * Configuration for any ElevenLabs adapter. When `apiKey` is omitted we read\n * `ELEVENLABS_API_KEY` from `process.env` / `window.env` to match the\n * pattern the realtime adapters already use.\n */\nexport interface ElevenLabsClientConfig {\n apiKey?: string\n
|
|
1
|
+
{"version":3,"file":"client.js","names":[],"sources":["../../../src/utils/client.ts"],"sourcesContent":["import { ElevenLabsClient } from '@elevenlabs/elevenlabs-js'\nimport {\n getApiKeyFromEnv,\n generateId as sharedGenerateId,\n} from '@tanstack/ai-utils'\nimport type { ElevenLabsOutputFormat } from '../model-meta'\n\n/**\n * Configuration for any ElevenLabs adapter. When `apiKey` is omitted we read\n * `ELEVENLABS_API_KEY` from `process.env` / `window.env` to match the\n * pattern the realtime adapters already use.\n */\nexport interface ElevenLabsClientConfig {\n apiKey?: string\n /**\n * Base URL for every request. Same option name as the other adapters, so a\n * gateway config can be spread into any of them. Wins over `baseUrl` when\n * both are set.\n */\n baseURL?: string\n /** Alias of `baseURL`. */\n baseUrl?: string\n /** Per-request timeout passed through to the SDK (ms). */\n timeoutInSeconds?: number\n /** Override the number of SDK-level retries. */\n maxRetries?: number\n /**\n * Headers sent with every request. Same option name as the other adapters.\n * Wins over `headers` when both are set.\n */\n defaultHeaders?: Record<string, string>\n /** Alias of `defaultHeaders`. */\n headers?: Record<string, string>\n}\n\ninterface EnvObject {\n ELEVENLABS_API_KEY?: string\n ELEVENLABS_AGENT_ID?: string\n}\n\ninterface WindowWithEnv {\n env?: EnvObject\n}\n\nfunction getEnvironment(): EnvObject | undefined {\n if (typeof globalThis !== 'undefined') {\n const win = (globalThis as { window?: WindowWithEnv }).window\n if (win?.env) return win.env\n }\n if (typeof process !== 'undefined') {\n return process.env as EnvObject\n }\n return undefined\n}\n\nexport function getElevenLabsApiKeyFromEnv(): string {\n return getApiKeyFromEnv('ELEVENLABS_API_KEY')\n}\n\nexport function getElevenLabsAgentIdFromEnv(): string {\n const id = getEnvironment()?.ELEVENLABS_AGENT_ID\n if (!id) {\n throw new Error(\n 'ELEVENLABS_AGENT_ID is required. Please set it in your environment ' +\n 'variables or pass `agentId` explicitly to elevenlabsRealtimeToken().',\n )\n }\n return id\n}\n\n/**\n * Build an `ElevenLabsClient` with env-based or explicit credentials.\n * Each adapter calls this once at construction time so unit tests can\n * pass in an explicit key without needing `process.env`.\n */\nexport function createElevenLabsClient(\n config?: ElevenLabsClientConfig,\n): ElevenLabsClient {\n const apiKey = config?.apiKey ?? getElevenLabsApiKeyFromEnv()\n const baseUrl = config?.baseURL ?? config?.baseUrl\n const headers = config?.defaultHeaders ?? config?.headers\n return new ElevenLabsClient({\n apiKey,\n ...(baseUrl ? { baseUrl } : {}),\n ...(config?.timeoutInSeconds != null\n ? { timeoutInSeconds: config.timeoutInSeconds }\n : {}),\n ...(config?.maxRetries != null ? { maxRetries: config.maxRetries } : {}),\n ...(headers ? { headers } : {}),\n })\n}\n\n// Re-exported from `@tanstack/ai-utils` so existing callers keep working\n// while the implementation stays deduped across provider packages.\nexport const generateId = sharedGenerateId\n\n/**\n * Convert an ArrayBuffer to base64 in a cross-runtime way.\n *\n * The naive `btoa(String.fromCharCode(...bytes))` form blows up V8's argument\n * limit (~65k) on realistic audio payloads, so we either use `Buffer`\n * (Node / Bun) or walk the byte array in a single loop (browser).\n */\nexport function arrayBufferToBase64(buffer: ArrayBuffer): string {\n if (typeof Buffer !== 'undefined' && typeof Buffer.from === 'function') {\n return Buffer.from(buffer).toString('base64')\n }\n const view = new Uint8Array(buffer)\n let binary = ''\n for (const byte of view) {\n binary += String.fromCharCode(byte)\n }\n return btoa(binary)\n}\n\n/**\n * Drain a `ReadableStream<Uint8Array>` (what the ElevenLabs SDK returns for\n * audio endpoints) into a single `Uint8Array`, then expose it as an\n * `ArrayBuffer` slice. We concatenate ourselves rather than going through\n * `new Response(stream).arrayBuffer()` so we stay runtime-agnostic.\n */\nexport async function readStreamToArrayBuffer(\n stream: ReadableStream<Uint8Array>,\n): Promise<ArrayBuffer> {\n const reader = stream.getReader()\n const chunks: Array<Uint8Array> = []\n let total = 0\n try {\n let result = await reader.read()\n while (!result.done) {\n chunks.push(result.value)\n total += result.value.byteLength\n result = await reader.read()\n }\n } finally {\n reader.releaseLock()\n }\n const merged = new Uint8Array(total)\n let offset = 0\n for (const chunk of chunks) {\n merged.set(chunk, offset)\n offset += chunk.byteLength\n }\n return merged.buffer.slice(\n merged.byteOffset,\n merged.byteOffset + merged.byteLength,\n )\n}\n\n/**\n * Decode a `data:` URL into a Blob for upload to the ElevenLabs STT API\n * (which only accepts multipart files or https URLs). Supports base64 and\n * URL-encoded payloads. Returns `undefined` for non-data-URL strings so the\n * caller can fall through to treating the input as an https URL.\n */\nexport function dataUrlToBlob(value: string): Blob | undefined {\n if (!value.startsWith('data:')) return undefined\n const commaIndex = value.indexOf(',')\n if (commaIndex === -1) return undefined\n\n const header = value.slice(5, commaIndex)\n const payload = value.slice(commaIndex + 1)\n const isBase64 = /;base64$/i.test(header)\n const mimeType = header.split(';')[0] || 'application/octet-stream'\n\n if (isBase64) {\n const binary = atob(payload)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i += 1) {\n bytes[i] = binary.charCodeAt(i)\n }\n return new Blob([bytes], { type: mimeType })\n }\n\n return new Blob([decodeURIComponent(payload)], { type: mimeType })\n}\n\n/**\n * Break an ElevenLabs `output_format` string (`mp3_44100_128`,\n * `pcm_24000`, `opus_48000_64`, `ulaw_8000`, ...) into a file extension and\n * content-type suitable for `TTSResult` / `AudioGenerationResult` consumers.\n *\n * Unknown codecs fall back to `mp3` / `audio/mpeg` because the ElevenLabs\n * default is `mp3_44100_128` — mispredicting on an exotic format is safer\n * than throwing in the adapter.\n */\nexport function parseOutputFormat(fmt: ElevenLabsOutputFormat | undefined): {\n format: string\n contentType: string\n} {\n const codec = (fmt || 'mp3_44100_128').split('_')[0]?.toLowerCase()\n switch (codec) {\n case 'mp3':\n return { format: 'mp3', contentType: 'audio/mpeg' }\n case 'pcm':\n return { format: 'pcm', contentType: 'audio/pcm' }\n case 'opus':\n return { format: 'opus', contentType: 'audio/opus' }\n case 'ulaw':\n return { format: 'ulaw', contentType: 'audio/basic' }\n case 'alaw':\n return { format: 'alaw', contentType: 'audio/x-alaw-basic' }\n case undefined:\n default:\n // `split('_')[0]?.toLowerCase()` can be `undefined` only if `fmt` is\n // an empty string; any other unknown codec also falls back to mp3.\n return { format: 'mp3', contentType: 'audio/mpeg' }\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/ai-elevenlabs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "ElevenLabs adapter for TanStack AI realtime voice, text-to-speech, transcription, music, and sound effects.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -57,11 +57,11 @@
|
|
|
57
57
|
"@tanstack/ai-utils": "^0.4.0"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"@tanstack/ai": "^0.52.
|
|
60
|
+
"@tanstack/ai": "^0.52.3"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@vitest/coverage-v8": "4.1.10",
|
|
64
|
-
"@tanstack/ai": "0.52.
|
|
64
|
+
"@tanstack/ai": "0.52.3"
|
|
65
65
|
},
|
|
66
66
|
"scripts": {
|
|
67
67
|
"build": "vite build",
|
package/src/utils/client.ts
CHANGED
|
@@ -12,13 +12,24 @@ import type { ElevenLabsOutputFormat } from '../model-meta'
|
|
|
12
12
|
*/
|
|
13
13
|
export interface ElevenLabsClientConfig {
|
|
14
14
|
apiKey?: string
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Base URL for every request. Same option name as the other adapters, so a
|
|
17
|
+
* gateway config can be spread into any of them. Wins over `baseUrl` when
|
|
18
|
+
* both are set.
|
|
19
|
+
*/
|
|
20
|
+
baseURL?: string
|
|
21
|
+
/** Alias of `baseURL`. */
|
|
16
22
|
baseUrl?: string
|
|
17
23
|
/** Per-request timeout passed through to the SDK (ms). */
|
|
18
24
|
timeoutInSeconds?: number
|
|
19
25
|
/** Override the number of SDK-level retries. */
|
|
20
26
|
maxRetries?: number
|
|
21
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Headers sent with every request. Same option name as the other adapters.
|
|
29
|
+
* Wins over `headers` when both are set.
|
|
30
|
+
*/
|
|
31
|
+
defaultHeaders?: Record<string, string>
|
|
32
|
+
/** Alias of `defaultHeaders`. */
|
|
22
33
|
headers?: Record<string, string>
|
|
23
34
|
}
|
|
24
35
|
|
|
@@ -66,14 +77,16 @@ export function createElevenLabsClient(
|
|
|
66
77
|
config?: ElevenLabsClientConfig,
|
|
67
78
|
): ElevenLabsClient {
|
|
68
79
|
const apiKey = config?.apiKey ?? getElevenLabsApiKeyFromEnv()
|
|
80
|
+
const baseUrl = config?.baseURL ?? config?.baseUrl
|
|
81
|
+
const headers = config?.defaultHeaders ?? config?.headers
|
|
69
82
|
return new ElevenLabsClient({
|
|
70
83
|
apiKey,
|
|
71
|
-
...(
|
|
84
|
+
...(baseUrl ? { baseUrl } : {}),
|
|
72
85
|
...(config?.timeoutInSeconds != null
|
|
73
86
|
? { timeoutInSeconds: config.timeoutInSeconds }
|
|
74
87
|
: {}),
|
|
75
88
|
...(config?.maxRetries != null ? { maxRetries: config.maxRetries } : {}),
|
|
76
|
-
...(
|
|
89
|
+
...(headers ? { headers } : {}),
|
|
77
90
|
})
|
|
78
91
|
}
|
|
79
92
|
|