@voquill/voice-ai 0.2.4 → 0.3.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/LICENCE +1 -1
- package/dist/elevenlabs.utils.d.ts +11 -0
- package/dist/elevenlabs.utils.d.ts.map +1 -1
- package/dist/elevenlabs.utils.js +43 -9
- package/dist/gemini.utils.js +1 -1
- package/dist/groq.utils.d.ts.map +1 -1
- package/dist/groq.utils.js +21 -12
- package/dist/openai.utils.js +1 -1
- package/package.json +8 -8
package/LICENCE
CHANGED
|
@@ -2,5 +2,16 @@ export type ElevenLabsTestIntegrationArgs = {
|
|
|
2
2
|
apiKey: string;
|
|
3
3
|
};
|
|
4
4
|
export declare const elevenlabsTestIntegration: ({ apiKey, }: ElevenLabsTestIntegrationArgs) => Promise<boolean>;
|
|
5
|
+
export type ElevenLabsTranscriptionArgs = {
|
|
6
|
+
apiKey: string;
|
|
7
|
+
blob: ArrayBuffer | Buffer;
|
|
8
|
+
ext: string;
|
|
9
|
+
language?: string;
|
|
10
|
+
};
|
|
11
|
+
export type ElevenLabsTranscribeAudioOutput = {
|
|
12
|
+
text: string;
|
|
13
|
+
wordsUsed: number;
|
|
14
|
+
};
|
|
15
|
+
export declare const elevenlabsTranscribeAudio: ({ apiKey, blob, ext, language, }: ElevenLabsTranscriptionArgs) => Promise<ElevenLabsTranscribeAudioOutput>;
|
|
5
16
|
export declare const convertFloat32ToBase64PCM16: (float32Array: Float32Array | number[]) => string;
|
|
6
17
|
//# sourceMappingURL=elevenlabs.utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elevenlabs.utils.d.ts","sourceRoot":"","sources":["../src/elevenlabs.utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"elevenlabs.utils.d.ts","sourceRoot":"","sources":["../src/elevenlabs.utils.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,6BAA6B,GAAG;IAC1C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAU,aAE7C,6BAA6B,KAAG,OAAO,CAAC,OAAO,CAcjD,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAU,kCAK7C,2BAA2B,KAAG,OAAO,CAAC,+BAA+B,CA4CvE,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,cAAc,YAAY,GAAG,MAAM,EAAE,KACpC,MAmBF,CAAC"}
|
package/dist/elevenlabs.utils.js
CHANGED
|
@@ -1,14 +1,48 @@
|
|
|
1
|
+
import { retry, countWords } from "@voquill/utilities";
|
|
1
2
|
export const elevenlabsTestIntegration = async ({ apiKey, }) => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
const response = await fetch("https://api.elevenlabs.io/v1/user", {
|
|
4
|
+
method: "GET",
|
|
5
|
+
headers: { "xi-api-key": apiKey },
|
|
6
|
+
});
|
|
7
|
+
if (!response.ok) {
|
|
8
|
+
const detail = await response.text().catch(() => "");
|
|
9
|
+
throw new Error(detail
|
|
10
|
+
? `ElevenLabs responded ${response.status}: ${detail}`
|
|
11
|
+
: `ElevenLabs responded with status ${response.status}`);
|
|
11
12
|
}
|
|
13
|
+
return true;
|
|
14
|
+
};
|
|
15
|
+
export const elevenlabsTranscribeAudio = async ({ apiKey, blob, ext, language, }) => {
|
|
16
|
+
return retry({
|
|
17
|
+
retries: 3,
|
|
18
|
+
fn: async () => {
|
|
19
|
+
const formData = new FormData();
|
|
20
|
+
const bodyData = blob instanceof ArrayBuffer ? blob : blob.buffer;
|
|
21
|
+
const audioBlob = new Blob([bodyData], { type: `audio/${ext}` });
|
|
22
|
+
formData.append("file", audioBlob, `audio.${ext}`);
|
|
23
|
+
formData.append("model_id", "scribe_v1");
|
|
24
|
+
if (language && language !== "auto") {
|
|
25
|
+
formData.append("language_code", language);
|
|
26
|
+
}
|
|
27
|
+
const response = await fetch("https://api.elevenlabs.io/v1/speech-to-text", {
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers: {
|
|
30
|
+
"xi-api-key": apiKey.trim(),
|
|
31
|
+
},
|
|
32
|
+
body: formData,
|
|
33
|
+
});
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
36
|
+
throw new Error(`ElevenLabs API request failed with status ${response.status}: ${errorText}`);
|
|
37
|
+
}
|
|
38
|
+
const data = (await response.json());
|
|
39
|
+
const transcript = data?.text;
|
|
40
|
+
if (!transcript) {
|
|
41
|
+
throw new Error("Transcription failed: No text in ElevenLabs API response");
|
|
42
|
+
}
|
|
43
|
+
return { text: transcript, wordsUsed: countWords(transcript) };
|
|
44
|
+
},
|
|
45
|
+
});
|
|
12
46
|
};
|
|
13
47
|
export const convertFloat32ToBase64PCM16 = (float32Array) => {
|
|
14
48
|
const samples = Array.isArray(float32Array)
|
package/dist/gemini.utils.js
CHANGED
|
@@ -60,7 +60,7 @@ export const geminiTranscribeAudio = async ({ apiKey, model = "gemini-2.5-flash"
|
|
|
60
60
|
}
|
|
61
61
|
const base64Audio = btoa(binary);
|
|
62
62
|
let transcriptionPrompt = "Transcribe this audio accurately.";
|
|
63
|
-
if (language) {
|
|
63
|
+
if (language && language !== "auto") {
|
|
64
64
|
transcriptionPrompt += ` The audio is in ${language}.`;
|
|
65
65
|
}
|
|
66
66
|
if (prompt) {
|
package/dist/groq.utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groq.utils.d.ts","sourceRoot":"","sources":["../src/groq.utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"groq.utils.d.ts","sourceRoot":"","sources":["../src/groq.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,cAAc,EACf,MAAM,gBAAgB,CAAC;AAUxB,eAAO,MAAM,oBAAoB,yIAKvB,CAAC;AACX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAYtE,eAAO,MAAM,oBAAoB,qCAAsC,CAAC;AACxE,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AA+BvE,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,iDAOvC,qBAAqB,KAAG,OAAO,CAAC,yBAAyB,CAqB3D,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,6DAO5C,oBAAoB,KAAG,OAAO,CAAC,0BAA0B,CAyD3D,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,aAEvC,uBAAuB,KAAG,OAAO,CAAC,OAAO,CAgC3C,CAAC;AAMF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,YAAY,CAAC;CACrB,CAAC;AAEF,wBAAuB,cAAc,CAAC,EACpC,MAAM,EACN,KAAK,EACL,KAAK,GACN,EAAE,kBAAkB,GAAG,cAAc,CAAC,cAAc,CAAC,CAOrD"}
|
package/dist/groq.utils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { countWords, retry } from "@voquill/utilities";
|
|
1
2
|
import Groq, { toFile } from "groq-sdk/index";
|
|
2
|
-
import { retry, countWords } from "@voquill/utilities";
|
|
3
3
|
import OpenAI from "openai";
|
|
4
4
|
import { openaiCompatibleStreamChat } from "./openai.utils";
|
|
5
5
|
export const GENERATE_TEXT_MODELS = [
|
|
@@ -8,6 +8,15 @@ export const GENERATE_TEXT_MODELS = [
|
|
|
8
8
|
"openai/gpt-oss-20b",
|
|
9
9
|
"openai/gpt-oss-120b",
|
|
10
10
|
];
|
|
11
|
+
// Models that support `response_format: { type: "json_schema" }`.
|
|
12
|
+
// See https://console.groq.com/docs/structured-outputs
|
|
13
|
+
const JSON_SCHEMA_SUPPORTED_MODELS = new Set([
|
|
14
|
+
"moonshotai/kimi-k2-instruct-0905",
|
|
15
|
+
"openai/gpt-oss-20b",
|
|
16
|
+
"openai/gpt-oss-120b",
|
|
17
|
+
"meta-llama/llama-4-scout-17b-16e-instruct",
|
|
18
|
+
"meta-llama/llama-4-maverick-17b-128e-instruct",
|
|
19
|
+
]);
|
|
11
20
|
export const TRANSCRIPTION_MODELS = ["whisper-large-v3-turbo"];
|
|
12
21
|
const contentToString = (content) => {
|
|
13
22
|
if (!content) {
|
|
@@ -42,7 +51,7 @@ export const groqTranscribeAudio = async ({ apiKey, model = "whisper-large-v3-tu
|
|
|
42
51
|
file,
|
|
43
52
|
model,
|
|
44
53
|
prompt,
|
|
45
|
-
language: language
|
|
54
|
+
language: language && language !== "auto" ? language : undefined,
|
|
46
55
|
});
|
|
47
56
|
if (!response.text) {
|
|
48
57
|
throw new Error("Transcription failed");
|
|
@@ -72,18 +81,18 @@ export const groqGenerateTextResponse = async ({ apiKey, model = "meta-llama/lla
|
|
|
72
81
|
const response = await client.chat.completions.create({
|
|
73
82
|
messages,
|
|
74
83
|
model,
|
|
75
|
-
temperature: 0,
|
|
76
84
|
max_completion_tokens: 8192,
|
|
77
|
-
top_p: 1,
|
|
78
85
|
response_format: jsonResponse
|
|
79
|
-
?
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
? JSON_SCHEMA_SUPPORTED_MODELS.has(model)
|
|
87
|
+
? {
|
|
88
|
+
type: "json_schema",
|
|
89
|
+
json_schema: {
|
|
90
|
+
name: jsonResponse.name,
|
|
91
|
+
description: jsonResponse.description,
|
|
92
|
+
schema: jsonResponse.schema,
|
|
93
|
+
},
|
|
94
|
+
}
|
|
95
|
+
: { type: "json_object" }
|
|
87
96
|
: undefined,
|
|
88
97
|
});
|
|
89
98
|
console.log("groq llm usage:", response.usage);
|
package/dist/openai.utils.js
CHANGED
|
@@ -48,7 +48,7 @@ export const openaiTranscribeAudio = async ({ apiKey, model = "whisper-1", blob,
|
|
|
48
48
|
file,
|
|
49
49
|
model,
|
|
50
50
|
prompt,
|
|
51
|
-
language: language
|
|
51
|
+
language: language && language !== "auto" ? language : undefined,
|
|
52
52
|
});
|
|
53
53
|
if (!response.text) {
|
|
54
54
|
throw new Error("Transcription failed");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voquill/voice-ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Shared Groq voice transcription helpers",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -15,19 +15,19 @@
|
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@anthropic-ai/sdk": "^0.71.2",
|
|
17
17
|
"@azure/openai": "^2.0.0",
|
|
18
|
-
"@google/genai": "^1.
|
|
18
|
+
"@google/genai": "^1.48.0",
|
|
19
19
|
"groq-sdk": "^0.37.0",
|
|
20
|
-
"microsoft-cognitiveservices-speech-sdk": "^1.
|
|
21
|
-
"openai": "^4.
|
|
20
|
+
"microsoft-cognitiveservices-speech-sdk": "^1.49.0",
|
|
21
|
+
"openai": "^4.104.0",
|
|
22
22
|
"wavefile": "^11.0.0",
|
|
23
23
|
"zod": "^3.25.76",
|
|
24
|
-
"zod-to-json-schema": "^3.
|
|
25
|
-
"@voquill/utilities": "0.
|
|
26
|
-
"@voquill/types": "0.
|
|
24
|
+
"zod-to-json-schema": "^3.25.2",
|
|
25
|
+
"@voquill/utilities": "0.3.0",
|
|
26
|
+
"@voquill/types": "0.3.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"typescript": "5.9.2",
|
|
30
|
-
"@voquill/typescript-config": "0.
|
|
30
|
+
"@voquill/typescript-config": "0.3.0"
|
|
31
31
|
},
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"access": "public"
|