@framers/agentos-ext-streaming-stt-deepgram 0.2.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/LICENSE +23 -0
- package/SKILL.md +62 -0
- package/dist/DeepgramDiarizationAdapter.d.ts +78 -0
- package/dist/DeepgramDiarizationAdapter.d.ts.map +1 -0
- package/dist/DeepgramDiarizationAdapter.js +78 -0
- package/dist/DeepgramDiarizationAdapter.js.map +1 -0
- package/dist/DeepgramStreamSession.d.ts +150 -0
- package/dist/DeepgramStreamSession.d.ts.map +1 -0
- package/dist/DeepgramStreamSession.js +351 -0
- package/dist/DeepgramStreamSession.js.map +1 -0
- package/dist/DeepgramStreamingSTT.d.ts +67 -0
- package/dist/DeepgramStreamingSTT.d.ts.map +1 -0
- package/dist/DeepgramStreamingSTT.js +81 -0
- package/dist/DeepgramStreamingSTT.js.map +1 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +64 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/manifest.json +8 -0
- package/package.json +46 -0
- package/src/DeepgramDiarizationAdapter.ts +113 -0
- package/src/DeepgramStreamSession.ts +462 -0
- package/src/DeepgramStreamingSTT.ts +97 -0
- package/src/index.ts +112 -0
- package/src/types.ts +71 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AA4BjE,iFAAiF;AACjF,MAAM,4BAA4B,GAAG,wBAAwB,CAAC;AAE9D,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAAc;IACvD,OAAO,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA6B;IAC/D,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC;IAC7D,MAAM,GAAG,GAAG,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAE7C,OAAO;QACL,EAAE,EAAE,wBAAwB;QAC5B,WAAW,EAAE;YACX;gBACE,EAAE,EAAE,wBAAwB;gBAC5B,IAAI,EAAE,4BAA4B;gBAClC,OAAO,EAAE,GAAG;gBACZ,eAAe,EAAE,IAAI;gBACrB,QAAQ,EAAE,EAAE,UAAU,EAAE,oBAAoB,EAAE;aAC/C;SACF;KACF,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EACL,uBAAuB,EACvB,eAAe,GAChB,MAAM,iCAAiC,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file types.ts
|
|
3
|
+
* @description Deepgram-specific configuration types for the streaming STT extension pack.
|
|
4
|
+
*
|
|
5
|
+
* These types augment the generic {@link StreamingSTTConfig} with Deepgram WebSocket
|
|
6
|
+
* API options that have no counterpart in the core voice pipeline interface.
|
|
7
|
+
*
|
|
8
|
+
* @module streaming-stt-deepgram/types
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Deepgram-specific configuration for the streaming STT session.
|
|
12
|
+
*
|
|
13
|
+
* All fields are optional — sensible defaults are applied when omitted.
|
|
14
|
+
* The `apiKey` field is required and must be a valid Deepgram API key.
|
|
15
|
+
*/
|
|
16
|
+
export interface DeepgramStreamingConfig {
|
|
17
|
+
/**
|
|
18
|
+
* Deepgram API key. Must be set to a non-empty string; the pack reads this
|
|
19
|
+
* from the `DEEPGRAM_API_KEY` secret when constructed via {@link createExtensionPack}.
|
|
20
|
+
*/
|
|
21
|
+
apiKey: string;
|
|
22
|
+
/**
|
|
23
|
+
* Deepgram model name.
|
|
24
|
+
* @defaultValue 'nova-2'
|
|
25
|
+
* @see {@link https://developers.deepgram.com/docs/models}
|
|
26
|
+
*/
|
|
27
|
+
model?: string;
|
|
28
|
+
/**
|
|
29
|
+
* BCP-47 language code for recognition (e.g. `'en-US'`, `'fr-FR'`).
|
|
30
|
+
* @defaultValue 'en-US'
|
|
31
|
+
*/
|
|
32
|
+
language?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Whether to insert punctuation into the transcript.
|
|
35
|
+
* @defaultValue true
|
|
36
|
+
*/
|
|
37
|
+
punctuate?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Whether to emit interim (non-final) transcript events.
|
|
40
|
+
* @defaultValue true
|
|
41
|
+
*/
|
|
42
|
+
interimResults?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Whether to enable speaker diarization (speaker turn segmentation).
|
|
45
|
+
* When `true`, each {@link TranscriptWord} in the result carries a `speaker`
|
|
46
|
+
* label populated by {@link extractSpeakerFromWords}.
|
|
47
|
+
* @defaultValue false
|
|
48
|
+
*/
|
|
49
|
+
diarize?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Custom keyword boosting list. Deepgram will upweight these terms during
|
|
52
|
+
* recognition. Format: `['keyword:boost']` where boost is an optional float.
|
|
53
|
+
* @see {@link https://developers.deepgram.com/docs/keywords}
|
|
54
|
+
*/
|
|
55
|
+
keywords?: string[];
|
|
56
|
+
/**
|
|
57
|
+
* Deepgram native endpointing duration in milliseconds.
|
|
58
|
+
* Set to `false` to disable provider-side endpointing (the voice pipeline's
|
|
59
|
+
* {@link IEndpointDetector} is then solely responsible for utterance segmentation).
|
|
60
|
+
* @defaultValue false
|
|
61
|
+
*/
|
|
62
|
+
endpointing?: number | false;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC9B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file types.ts
|
|
3
|
+
* @description Deepgram-specific configuration types for the streaming STT extension pack.
|
|
4
|
+
*
|
|
5
|
+
* These types augment the generic {@link StreamingSTTConfig} with Deepgram WebSocket
|
|
6
|
+
* API options that have no counterpart in the core voice pipeline interface.
|
|
7
|
+
*
|
|
8
|
+
* @module streaming-stt-deepgram/types
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
package/manifest.json
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@framers/agentos-ext-streaming-stt-deepgram",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Real-time streaming STT via Deepgram WebSocket API",
|
|
5
|
+
"kind": "streaming-stt-provider",
|
|
6
|
+
"extensionId": "streaming-stt-deepgram",
|
|
7
|
+
"entryPoint": "./dist/index.js"
|
|
8
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@framers/agentos-ext-streaming-stt-deepgram",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Real-time streaming STT via Deepgram WebSocket API for AgentOS voice pipeline",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"src",
|
|
17
|
+
"SKILL.md",
|
|
18
|
+
"manifest.json"
|
|
19
|
+
],
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@framers/agentos": "^0.1.0"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"ws": "^8.17.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"typescript": "^5.5.0",
|
|
28
|
+
"vitest": "^1.6.0",
|
|
29
|
+
"@types/ws": "^8.5.0",
|
|
30
|
+
"@framers/agentos": "0.1.94"
|
|
31
|
+
},
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"author": "Frame.dev",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/framersai/agentos-extensions.git",
|
|
37
|
+
"directory": "registry/curated/voice/streaming-stt-deepgram"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc -p tsconfig.json",
|
|
44
|
+
"test": "vitest run"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file DeepgramDiarizationAdapter.ts
|
|
3
|
+
* @description Utilities for extracting speaker labels from Deepgram word-level
|
|
4
|
+
* diarization results.
|
|
5
|
+
*
|
|
6
|
+
* Deepgram's `diarize: true` option annotates each word in the transcript with
|
|
7
|
+
* a zero-indexed integer `speaker` field. This module converts that raw
|
|
8
|
+
* numeric label into the string format expected by {@link TranscriptWord.speaker}
|
|
9
|
+
* (`'Speaker_0'`, `'Speaker_1'`, …) and determines the majority speaker for
|
|
10
|
+
* an utterance.
|
|
11
|
+
*
|
|
12
|
+
* @module streaming-stt-deepgram/DeepgramDiarizationAdapter
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A single Deepgram word object as returned by the WebSocket API when
|
|
17
|
+
* `diarize: true` is passed in the connection query string.
|
|
18
|
+
*
|
|
19
|
+
* Only the fields used by this adapter are declared; the raw JSON may contain
|
|
20
|
+
* additional fields that are ignored.
|
|
21
|
+
*/
|
|
22
|
+
export interface DeepgramWord {
|
|
23
|
+
/** Recognised word token. */
|
|
24
|
+
word: string;
|
|
25
|
+
/** Start time relative to the stream start in seconds. */
|
|
26
|
+
start: number;
|
|
27
|
+
/** End time relative to the stream start in seconds. */
|
|
28
|
+
end: number;
|
|
29
|
+
/** Recognition confidence in [0, 1]. */
|
|
30
|
+
confidence: number;
|
|
31
|
+
/**
|
|
32
|
+
* Zero-indexed speaker index assigned by Deepgram's diarization model.
|
|
33
|
+
* Present only when the session was opened with `diarize=true`.
|
|
34
|
+
*/
|
|
35
|
+
speaker?: number;
|
|
36
|
+
/** Punctuated variant of {@link word} when `punctuate=true`. */
|
|
37
|
+
punctuated_word?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Extract the majority speaker label from an array of Deepgram word objects.
|
|
42
|
+
*
|
|
43
|
+
* The function tallies votes by `speaker` index and returns the label for the
|
|
44
|
+
* speaker with the most words. Ties are broken by lowest index (i.e. the
|
|
45
|
+
* earliest-assigned speaker wins).
|
|
46
|
+
*
|
|
47
|
+
* Returns `undefined` when the array is empty or no word carries a `speaker`
|
|
48
|
+
* field (i.e. diarization was not requested for this session).
|
|
49
|
+
*
|
|
50
|
+
* @param words - Raw Deepgram word objects from `channel.alternatives[0].words`.
|
|
51
|
+
* @returns A string label such as `'Speaker_0'`, or `undefined`.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* const words = [
|
|
56
|
+
* { word: 'Hello', speaker: 0, start: 0, end: 0.3, confidence: 0.99 },
|
|
57
|
+
* { word: 'world', speaker: 1, start: 0.4, end: 0.7, confidence: 0.97 },
|
|
58
|
+
* { word: 'today', speaker: 0, start: 0.8, end: 1.1, confidence: 0.95 },
|
|
59
|
+
* ];
|
|
60
|
+
* extractSpeakerFromWords(words); // → 'Speaker_0'
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export function extractSpeakerFromWords(words: DeepgramWord[]): string | undefined {
|
|
64
|
+
if (words.length === 0) return undefined;
|
|
65
|
+
|
|
66
|
+
/** Vote counts keyed by speaker index. */
|
|
67
|
+
const votes = new Map<number, number>();
|
|
68
|
+
|
|
69
|
+
for (const w of words) {
|
|
70
|
+
if (w.speaker === undefined) continue;
|
|
71
|
+
votes.set(w.speaker, (votes.get(w.speaker) ?? 0) + 1);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (votes.size === 0) return undefined;
|
|
75
|
+
|
|
76
|
+
// Find the speaker index with the highest vote count; ties broken by lowest index.
|
|
77
|
+
let majorityIndex = -1;
|
|
78
|
+
let majorityCount = -1;
|
|
79
|
+
|
|
80
|
+
for (const [index, count] of votes) {
|
|
81
|
+
if (count > majorityCount || (count === majorityCount && index < majorityIndex)) {
|
|
82
|
+
majorityCount = count;
|
|
83
|
+
majorityIndex = index;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return majorityIndex >= 0 ? `Speaker_${majorityIndex}` : undefined;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Map a Deepgram word object to the canonical `TranscriptWord`-compatible shape.
|
|
92
|
+
*
|
|
93
|
+
* Seconds are converted to milliseconds to match the voice pipeline convention.
|
|
94
|
+
* The `word` field prefers the punctuated variant when available.
|
|
95
|
+
*
|
|
96
|
+
* @param dw - Raw Deepgram word object.
|
|
97
|
+
* @returns A plain object matching the {@link TranscriptWord} interface.
|
|
98
|
+
*/
|
|
99
|
+
export function mapDeepgramWord(dw: DeepgramWord): {
|
|
100
|
+
word: string;
|
|
101
|
+
start: number;
|
|
102
|
+
end: number;
|
|
103
|
+
confidence: number;
|
|
104
|
+
speaker?: string;
|
|
105
|
+
} {
|
|
106
|
+
return {
|
|
107
|
+
word: dw.punctuated_word ?? dw.word,
|
|
108
|
+
start: Math.round(dw.start * 1000),
|
|
109
|
+
end: Math.round(dw.end * 1000),
|
|
110
|
+
confidence: dw.confidence,
|
|
111
|
+
speaker: dw.speaker !== undefined ? `Speaker_${dw.speaker}` : undefined,
|
|
112
|
+
};
|
|
113
|
+
}
|