@volley/recognition-client-sdk 0.1.297 → 0.1.381
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/dist/browser.bundled.d.ts +52 -14
- package/dist/index.bundled.d.ts +64 -24
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +146 -90
- package/dist/index.js.map +4 -4
- package/dist/recog-client-sdk.browser.js +85 -81
- package/dist/recog-client-sdk.browser.js.map +4 -4
- package/dist/recognition-client.d.ts +4 -0
- package/dist/recognition-client.d.ts.map +1 -1
- package/dist/simplified-vgf-recognition-client.d.ts +2 -0
- package/dist/simplified-vgf-recognition-client.d.ts.map +1 -1
- package/dist/vgf-recognition-state.d.ts +9 -0
- package/dist/vgf-recognition-state.d.ts.map +1 -1
- package/package.json +23 -23
- package/src/index.ts +2 -0
- package/src/recognition-client.ts +54 -2
- package/src/simplified-vgf-recognition-client.spec.ts +294 -12
- package/src/simplified-vgf-recognition-client.ts +68 -12
- package/src/vgf-recognition-state.ts +12 -0
|
@@ -100,6 +100,10 @@ export declare class RealTimeTwoWayWebSocketRecognitionClient extends WebSocketA
|
|
|
100
100
|
getStats(): IRecognitionClientStats;
|
|
101
101
|
protected onConnected(): void;
|
|
102
102
|
protected onDisconnected(code: number, reason: string): void;
|
|
103
|
+
/**
|
|
104
|
+
* Get human-readable description for WebSocket close code
|
|
105
|
+
*/
|
|
106
|
+
private getCloseCodeDescription;
|
|
103
107
|
protected onError(error: Event): void;
|
|
104
108
|
protected onMessage(msg: {
|
|
105
109
|
v: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recognition-client.d.ts","sourceRoot":"","sources":["../src/recognition-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAML,KAAK,qBAAqB,EAS3B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,EACV,kBAAkB,EAClB,uBAAuB,EACvB,8CAA8C,EAE/C,MAAM,+BAA+B,CAAC;AAUvC;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAgCD;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAGxD,YAAY,EAAE,8CAA8C,EAAE,MAAM,+BAA+B,CAAC;AAgCpG;;;;;GAKG;AACH,qBAAa,wCACX,SAAQ,oBAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAC7C,YAAW,kBAAkB;IAE7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAK;IAE7C,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,iBAAiB,CAA4B;IAGrD,OAAO,CAAC,iBAAiB,CAAS;IAGlC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,qBAAqB,CAAO;IACpC,OAAO,CAAC,iBAAiB,CAAK;gBAElB,MAAM,EAAE,8CAA8C;IA8ElE;;;;;;OAMG;IACH,OAAO,CAAC,GAAG;IAWX;;;OAGG;IACH,OAAO,CAAC,OAAO;IAmBA,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BvC;;;OAGG;YACW,gBAAgB;IAkIrB,SAAS,CAAC,SAAS,EAAE,WAAW,GAAG,eAAe,GAAG,IAAI,GAAG,IAAI;IAiBzE,OAAO,CAAC,iBAAiB;IAsCnB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAoCpC,cAAc,IAAI,IAAI;IAwBtB,mBAAmB,IAAI,MAAM;IAI7B,MAAM,IAAI,MAAM;IAIhB,QAAQ,IAAI,WAAW;IAIvB,WAAW,IAAI,OAAO;IAItB,YAAY,IAAI,OAAO;IAIvB,UAAU,IAAI,OAAO;IAIrB,uBAAuB,IAAI,OAAO;IAIlC,mBAAmB,IAAI,OAAO;IAI9B,QAAQ,IAAI,uBAAuB;IAgBnC,SAAS,CAAC,WAAW,IAAI,IAAI;IAiE7B,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"recognition-client.d.ts","sourceRoot":"","sources":["../src/recognition-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAML,KAAK,qBAAqB,EAS3B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,EACV,kBAAkB,EAClB,uBAAuB,EACvB,8CAA8C,EAE/C,MAAM,+BAA+B,CAAC;AAUvC;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAgCD;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAGxD,YAAY,EAAE,8CAA8C,EAAE,MAAM,+BAA+B,CAAC;AAgCpG;;;;;GAKG;AACH,qBAAa,wCACX,SAAQ,oBAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAC7C,YAAW,kBAAkB;IAE7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAK;IAE7C,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,iBAAiB,CAA4B;IAGrD,OAAO,CAAC,iBAAiB,CAAS;IAGlC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,qBAAqB,CAAO;IACpC,OAAO,CAAC,iBAAiB,CAAK;gBAElB,MAAM,EAAE,8CAA8C;IA8ElE;;;;;;OAMG;IACH,OAAO,CAAC,GAAG;IAWX;;;OAGG;IACH,OAAO,CAAC,OAAO;IAmBA,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BvC;;;OAGG;YACW,gBAAgB;IAkIrB,SAAS,CAAC,SAAS,EAAE,WAAW,GAAG,eAAe,GAAG,IAAI,GAAG,IAAI;IAiBzE,OAAO,CAAC,iBAAiB;IAsCnB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAoCpC,cAAc,IAAI,IAAI;IAwBtB,mBAAmB,IAAI,MAAM;IAI7B,MAAM,IAAI,MAAM;IAIhB,QAAQ,IAAI,WAAW;IAIvB,WAAW,IAAI,OAAO;IAItB,YAAY,IAAI,OAAO;IAIvB,UAAU,IAAI,OAAO;IAIrB,uBAAuB,IAAI,OAAO;IAIlC,mBAAmB,IAAI,OAAO;IAI9B,QAAQ,IAAI,uBAAuB;IAgBnC,SAAS,CAAC,WAAW,IAAI,IAAI;IAiE7B,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IA8C5D;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAwB/B,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;cAYlB,SAAS,CAAC,GAAG,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,GAAG,CAAA;KAAE,GAAG,IAAI;IAQ/E;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAyB5B;;;OAGG;IACH,OAAO,CAAC,YAAY;CAuBrB"}
|
|
@@ -111,6 +111,8 @@ export declare class SimplifiedVGFRecognitionClient implements ISimplifiedVGFRec
|
|
|
111
111
|
private state;
|
|
112
112
|
private isRecordingAudio;
|
|
113
113
|
private stateChangeCallback;
|
|
114
|
+
private expectedUuid;
|
|
115
|
+
private logger;
|
|
114
116
|
constructor(config: SimplifiedVGFClientConfig);
|
|
115
117
|
connect(): Promise<void>;
|
|
116
118
|
sendAudio(audioData: ArrayBuffer | ArrayBufferView | Blob): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simplified-vgf-recognition-client.d.ts","sourceRoot":"","sources":["../src/simplified-vgf-recognition-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACH,gBAAgB,EAGnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEH,wBAAwB,EACxB,WAAW,EACd,MAAM,+BAA+B,CAAC;AAWvC;;GAEG;AACH,MAAM,WAAW,yBAA0B,SAAQ,wBAAwB;IACvE;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAElD;;;OAGG;IACH,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,WAAW,+BAA+B;IAE5C;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB;;;OAGG;IACH,SAAS,CAAC,SAAS,EAAE,WAAW,GAAG,eAAe,GAAG,IAAI,GAAG,IAAI,CAAC;IAEjE;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/B;;;;;;;;;;;;;;;;OAgBG;IACH,cAAc,IAAI,IAAI,CAAC;IAGvB;;;OAGG;IACH,WAAW,IAAI,gBAAgB,CAAC;IAGhC;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC;IAEvB;;OAEG;IACH,YAAY,IAAI,OAAO,CAAC;IAExB;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC;IAEtB;;OAEG;IACH,uBAAuB,IAAI,OAAO,CAAC;IAEnC;;OAEG;IACH,mBAAmB,IAAI,OAAO,CAAC;IAG/B;;OAEG;IACH,mBAAmB,IAAI,MAAM,CAAC;IAE9B;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,IAAI,WAAW,CAAC;CAE3B;AAED;;;GAGG;AACH,qBAAa,8BAA+B,YAAW,+BAA+B;IAClF,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,OAAO,CAAC,mBAAmB,CAAkD;
|
|
1
|
+
{"version":3,"file":"simplified-vgf-recognition-client.d.ts","sourceRoot":"","sources":["../src/simplified-vgf-recognition-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACH,gBAAgB,EAGnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEH,wBAAwB,EACxB,WAAW,EACd,MAAM,+BAA+B,CAAC;AAWvC;;GAEG;AACH,MAAM,WAAW,yBAA0B,SAAQ,wBAAwB;IACvE;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAElD;;;OAGG;IACH,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,WAAW,+BAA+B;IAE5C;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB;;;OAGG;IACH,SAAS,CAAC,SAAS,EAAE,WAAW,GAAG,eAAe,GAAG,IAAI,GAAG,IAAI,CAAC;IAEjE;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/B;;;;;;;;;;;;;;;;OAgBG;IACH,cAAc,IAAI,IAAI,CAAC;IAGvB;;;OAGG;IACH,WAAW,IAAI,gBAAgB,CAAC;IAGhC;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC;IAEvB;;OAEG;IACH,YAAY,IAAI,OAAO,CAAC;IAExB;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC;IAEtB;;OAEG;IACH,uBAAuB,IAAI,OAAO,CAAC;IAEnC;;OAEG;IACH,mBAAmB,IAAI,OAAO,CAAC;IAG/B;;OAEG;IACH,mBAAmB,IAAI,MAAM,CAAC;IAE9B;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,IAAI,WAAW,CAAC;CAE3B;AAED;;;GAGG;AACH,qBAAa,8BAA+B,YAAW,+BAA+B;IAClF,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,OAAO,CAAC,mBAAmB,CAAkD;IAC7E,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAqC;gBAEvC,MAAM,EAAE,yBAAyB;IA0LvC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B,SAAS,CAAC,SAAS,EAAE,WAAW,GAAG,eAAe,GAAG,IAAI,GAAG,IAAI;IAc1D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAOpC,cAAc,IAAI,IAAI;IAiCtB,mBAAmB,IAAI,MAAM;IAI7B,MAAM,IAAI,MAAM;IAIhB,QAAQ,IAAI,WAAW;IAIvB,WAAW,IAAI,OAAO;IAItB,YAAY,IAAI,OAAO;IAIvB,UAAU,IAAI,OAAO;IAIrB,uBAAuB,IAAI,OAAO;IAIlC,mBAAmB,IAAI,OAAO;IAM9B,WAAW,IAAI,gBAAgB;IAI/B,OAAO,CAAC,iBAAiB;CAM5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,yBAAyB,GAAG,+BAA+B,CAE5G"}
|
|
@@ -28,6 +28,7 @@ export declare const RecognitionVGFStateSchema: z.ZodObject<{
|
|
|
28
28
|
functionCallConfidence: z.ZodOptional<z.ZodNumber>;
|
|
29
29
|
finalFunctionCallTimestamp: z.ZodOptional<z.ZodString>;
|
|
30
30
|
promptSlotMap: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
|
|
31
|
+
recognitionActionProcessingState: z.ZodOptional<z.ZodString>;
|
|
31
32
|
}, "strip", z.ZodTypeAny, {
|
|
32
33
|
audioUtteranceId: string;
|
|
33
34
|
pendingTranscript: string;
|
|
@@ -44,6 +45,7 @@ export declare const RecognitionVGFStateSchema: z.ZodObject<{
|
|
|
44
45
|
functionCallConfidence?: number | undefined;
|
|
45
46
|
finalFunctionCallTimestamp?: string | undefined;
|
|
46
47
|
promptSlotMap?: Record<string, string[]> | undefined;
|
|
48
|
+
recognitionActionProcessingState?: string | undefined;
|
|
47
49
|
}, {
|
|
48
50
|
audioUtteranceId: string;
|
|
49
51
|
startRecordingStatus?: string | undefined;
|
|
@@ -60,6 +62,7 @@ export declare const RecognitionVGFStateSchema: z.ZodObject<{
|
|
|
60
62
|
functionCallConfidence?: number | undefined;
|
|
61
63
|
finalFunctionCallTimestamp?: string | undefined;
|
|
62
64
|
promptSlotMap?: Record<string, string[]> | undefined;
|
|
65
|
+
recognitionActionProcessingState?: string | undefined;
|
|
63
66
|
}>;
|
|
64
67
|
export type RecognitionState = z.infer<typeof RecognitionVGFStateSchema>;
|
|
65
68
|
export declare const RecordingStatus: {
|
|
@@ -77,6 +80,12 @@ export declare const TranscriptionStatus: {
|
|
|
77
80
|
readonly ERROR: "ERROR";
|
|
78
81
|
};
|
|
79
82
|
export type TranscriptionStatusType = typeof TranscriptionStatus[keyof typeof TranscriptionStatus];
|
|
83
|
+
export declare const RecognitionActionProcessingState: {
|
|
84
|
+
readonly NOT_STARTED: "NOT_STARTED";
|
|
85
|
+
readonly IN_PROGRESS: "IN_PROGRESS";
|
|
86
|
+
readonly COMPLETED: "COMPLETED";
|
|
87
|
+
};
|
|
88
|
+
export type RecognitionActionProcessingStateType = typeof RecognitionActionProcessingState[keyof typeof RecognitionActionProcessingState];
|
|
80
89
|
export declare function createInitialRecognitionState(audioUtteranceId: string): RecognitionState;
|
|
81
90
|
export declare function isValidRecordingStatusTransition(from: string | undefined, to: string): boolean;
|
|
82
91
|
//# sourceMappingURL=vgf-recognition-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vgf-recognition-state.d.ts","sourceRoot":"","sources":["../src/vgf-recognition-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB
|
|
1
|
+
{"version":3,"file":"vgf-recognition-state.d.ts","sourceRoot":"","sources":["../src/vgf-recognition-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BpC,CAAA;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAGxE,eAAO,MAAM,eAAe;;;;;CAKlB,CAAA;AAEV,MAAM,MAAM,mBAAmB,GAAG,OAAO,eAAe,CAAC,MAAM,OAAO,eAAe,CAAC,CAAA;AAEtF,eAAO,MAAM,mBAAmB;;;;;;CAMtB,CAAA;AAEV,MAAM,MAAM,uBAAuB,GAAG,OAAO,mBAAmB,CAAC,MAAM,OAAO,mBAAmB,CAAC,CAAA;AAElG,eAAO,MAAM,gCAAgC;;;;CAInC,CAAA;AAEV,MAAM,MAAM,oCAAoC,GAAG,OAAO,gCAAgC,CAAC,MAAM,OAAO,gCAAgC,CAAC,CAAA;AAGzI,wBAAgB,6BAA6B,CAAC,gBAAgB,EAAE,MAAM,GAAG,gBAAgB,CAQxF;AAGD,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAa9F"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volley/recognition-client-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.381",
|
|
4
4
|
"description": "Recognition Service TypeScript/Node.js Client SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -31,33 +31,33 @@
|
|
|
31
31
|
"provenance": true
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"uuid": "
|
|
34
|
+
"uuid": "11.0.0",
|
|
35
35
|
"ws": "8.18.3",
|
|
36
|
-
"zod": "
|
|
36
|
+
"zod": "3.22.4"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@semantic-release/changelog": "
|
|
40
|
-
"@semantic-release/commit-analyzer": "
|
|
41
|
-
"@semantic-release/exec": "
|
|
42
|
-
"@semantic-release/git": "
|
|
43
|
-
"@semantic-release/github": "
|
|
44
|
-
"@semantic-release/npm": "
|
|
45
|
-
"@semantic-release/release-notes-generator": "
|
|
46
|
-
"@types/jest": "
|
|
47
|
-
"@types/node": "
|
|
48
|
-
"@types/uuid": "
|
|
49
|
-
"@types/ws": "
|
|
50
|
-
"esbuild": "
|
|
51
|
-
"jest": "
|
|
52
|
-
"rollup": "
|
|
53
|
-
"rollup-plugin-dts": "
|
|
54
|
-
"semantic-release": "
|
|
55
|
-
"ts-jest": "
|
|
56
|
-
"typescript": "
|
|
57
|
-
"@recog/shared-
|
|
39
|
+
"@semantic-release/changelog": "6.0.3",
|
|
40
|
+
"@semantic-release/commit-analyzer": "13.0.1",
|
|
41
|
+
"@semantic-release/exec": "7.1.0",
|
|
42
|
+
"@semantic-release/git": "10.0.1",
|
|
43
|
+
"@semantic-release/github": "12.0.0",
|
|
44
|
+
"@semantic-release/npm": "13.1.1",
|
|
45
|
+
"@semantic-release/release-notes-generator": "14.1.0",
|
|
46
|
+
"@types/jest": "30.0.0",
|
|
47
|
+
"@types/node": "20.4.5",
|
|
48
|
+
"@types/uuid": "10.0.0",
|
|
49
|
+
"@types/ws": "8.5.5",
|
|
50
|
+
"esbuild": "0.25.0",
|
|
51
|
+
"jest": "29.6.1",
|
|
52
|
+
"rollup": "4.52.5",
|
|
53
|
+
"rollup-plugin-dts": "6.2.3",
|
|
54
|
+
"semantic-release": "25.0.1",
|
|
55
|
+
"ts-jest": "29.4.5",
|
|
56
|
+
"typescript": "5.1.6",
|
|
57
|
+
"@recog/shared-config": "1.0.0",
|
|
58
58
|
"@recog/websocket": "1.0.0",
|
|
59
59
|
"@recog/shared-utils": "1.0.0",
|
|
60
|
-
"@recog/shared-
|
|
60
|
+
"@recog/shared-types": "1.0.0"
|
|
61
61
|
},
|
|
62
62
|
"keywords": [
|
|
63
63
|
"recognition",
|
package/src/index.ts
CHANGED
|
@@ -682,7 +682,20 @@ export class RealTimeTwoWayWebSocketRecognitionClient
|
|
|
682
682
|
}
|
|
683
683
|
|
|
684
684
|
protected onDisconnected(code: number, reason: string): void {
|
|
685
|
-
|
|
685
|
+
// DIAGNOSTIC: Enhanced logging for disconnections
|
|
686
|
+
const closeCodeDescription = this.getCloseCodeDescription(code);
|
|
687
|
+
const is1006 = code === 1006;
|
|
688
|
+
|
|
689
|
+
this.log('debug', '[DIAGNOSTIC] WebSocket disconnected', {
|
|
690
|
+
code,
|
|
691
|
+
codeDescription: closeCodeDescription,
|
|
692
|
+
reason: reason || '(empty)',
|
|
693
|
+
previousState: this.state,
|
|
694
|
+
is1006Abnormal: is1006,
|
|
695
|
+
audioChunksSent: this.audioChunksSent,
|
|
696
|
+
audioBytesSent: this.audioBytesSent,
|
|
697
|
+
bufferStats: this.audioBuffer.getStats()
|
|
698
|
+
});
|
|
686
699
|
|
|
687
700
|
// Update state based on disconnection type
|
|
688
701
|
if (this.state === ClientState.STOPPING) {
|
|
@@ -692,7 +705,19 @@ export class RealTimeTwoWayWebSocketRecognitionClient
|
|
|
692
705
|
this.state === ClientState.READY ||
|
|
693
706
|
this.state === ClientState.CONNECTING
|
|
694
707
|
) {
|
|
695
|
-
this.log('error', 'Unexpected disconnection', {
|
|
708
|
+
this.log('error', '[DIAGNOSTIC] Unexpected disconnection', {
|
|
709
|
+
code,
|
|
710
|
+
codeDescription: closeCodeDescription,
|
|
711
|
+
reason: reason || '(empty)',
|
|
712
|
+
is1006: is1006,
|
|
713
|
+
possibleCauses: is1006 ? [
|
|
714
|
+
'Network connection lost',
|
|
715
|
+
'Server process crashed',
|
|
716
|
+
'Provider (Deepgram/AssemblyAI) WebSocket closed abnormally',
|
|
717
|
+
'Firewall/proxy terminated connection',
|
|
718
|
+
'Browser/tab suspended (mobile)'
|
|
719
|
+
] : []
|
|
720
|
+
});
|
|
696
721
|
this.state = ClientState.FAILED;
|
|
697
722
|
}
|
|
698
723
|
|
|
@@ -702,6 +727,33 @@ export class RealTimeTwoWayWebSocketRecognitionClient
|
|
|
702
727
|
this.config.onDisconnected(code, reason);
|
|
703
728
|
}
|
|
704
729
|
|
|
730
|
+
/**
|
|
731
|
+
* Get human-readable description for WebSocket close code
|
|
732
|
+
*/
|
|
733
|
+
private getCloseCodeDescription(code: number): string {
|
|
734
|
+
const descriptions: Record<number, string> = {
|
|
735
|
+
1000: 'Normal Closure',
|
|
736
|
+
1001: 'Going Away',
|
|
737
|
+
1002: 'Protocol Error',
|
|
738
|
+
1003: 'Unsupported Data',
|
|
739
|
+
1005: 'No Status Received',
|
|
740
|
+
1006: 'Abnormal Closure (no close frame received)',
|
|
741
|
+
1007: 'Invalid Frame Payload',
|
|
742
|
+
1008: 'Policy Violation',
|
|
743
|
+
1009: 'Message Too Big',
|
|
744
|
+
1010: 'Mandatory Extension',
|
|
745
|
+
1011: 'Internal Server Error',
|
|
746
|
+
1012: 'Service Restart',
|
|
747
|
+
1013: 'Try Again Later',
|
|
748
|
+
4000: 'Auth Required',
|
|
749
|
+
4001: 'Auth Failed',
|
|
750
|
+
4002: 'Rate Limit Exceeded',
|
|
751
|
+
4003: 'Invalid Session',
|
|
752
|
+
4004: 'Session Expired'
|
|
753
|
+
};
|
|
754
|
+
return descriptions[code] || `Unknown (${code})`;
|
|
755
|
+
}
|
|
756
|
+
|
|
705
757
|
protected onError(error: Event): void {
|
|
706
758
|
this.state = ClientState.FAILED;
|
|
707
759
|
|
|
@@ -65,6 +65,65 @@ describe('SimplifiedVGFRecognitionClient', () => {
|
|
|
65
65
|
expect(state.pendingTranscript).toBe('');
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
+
it('should generate new UUID when initial state has no audioUtteranceId', () => {
|
|
69
|
+
const initialState: RecognitionState = {
|
|
70
|
+
// No audioUtteranceId provided
|
|
71
|
+
startRecordingStatus: RecordingStatus.READY,
|
|
72
|
+
transcriptionStatus: TranscriptionStatus.NOT_STARTED,
|
|
73
|
+
pendingTranscript: ''
|
|
74
|
+
} as RecognitionState;
|
|
75
|
+
|
|
76
|
+
simplifiedClient = new SimplifiedVGFRecognitionClient({
|
|
77
|
+
initialState,
|
|
78
|
+
asrRequestConfig: {
|
|
79
|
+
provider: 'deepgram',
|
|
80
|
+
language: 'en',
|
|
81
|
+
sampleRate: 16000,
|
|
82
|
+
encoding: AudioEncoding.LINEAR16
|
|
83
|
+
},
|
|
84
|
+
onStateChange: stateChangeCallback
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const state = simplifiedClient.getVGFState();
|
|
88
|
+
// Should have generated a new UUID
|
|
89
|
+
expect(state.audioUtteranceId).toBeDefined();
|
|
90
|
+
expect(state.audioUtteranceId).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i);
|
|
91
|
+
// Should preserve other fields
|
|
92
|
+
expect(state.startRecordingStatus).toBe(RecordingStatus.READY);
|
|
93
|
+
expect(state.transcriptionStatus).toBe(TranscriptionStatus.NOT_STARTED);
|
|
94
|
+
|
|
95
|
+
// onStateChange should be called with the new UUID
|
|
96
|
+
expect(stateChangeCallback).toHaveBeenCalledTimes(1);
|
|
97
|
+
const callbackState = stateChangeCallback.mock.calls[0][0];
|
|
98
|
+
expect(callbackState.audioUtteranceId).toBe(state.audioUtteranceId);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should generate new UUID when initial state has empty audioUtteranceId', () => {
|
|
102
|
+
const initialState: RecognitionState = {
|
|
103
|
+
audioUtteranceId: '', // Empty UUID
|
|
104
|
+
startRecordingStatus: RecordingStatus.READY,
|
|
105
|
+
transcriptionStatus: TranscriptionStatus.NOT_STARTED,
|
|
106
|
+
pendingTranscript: ''
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
simplifiedClient = new SimplifiedVGFRecognitionClient({
|
|
110
|
+
initialState,
|
|
111
|
+
asrRequestConfig: {
|
|
112
|
+
provider: 'deepgram',
|
|
113
|
+
language: 'en',
|
|
114
|
+
sampleRate: 16000,
|
|
115
|
+
encoding: AudioEncoding.LINEAR16
|
|
116
|
+
},
|
|
117
|
+
onStateChange: stateChangeCallback
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const state = simplifiedClient.getVGFState();
|
|
121
|
+
// Should have generated a new UUID
|
|
122
|
+
expect(state.audioUtteranceId).toBeDefined();
|
|
123
|
+
expect(state.audioUtteranceId).not.toBe('');
|
|
124
|
+
expect(state.audioUtteranceId).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i);
|
|
125
|
+
});
|
|
126
|
+
|
|
68
127
|
it('should accept initial state and use its audioUtteranceId', () => {
|
|
69
128
|
const initialState: RecognitionState = {
|
|
70
129
|
audioUtteranceId: 'existing-session-id',
|
|
@@ -229,8 +288,11 @@ describe('SimplifiedVGFRecognitionClient', () => {
|
|
|
229
288
|
});
|
|
230
289
|
|
|
231
290
|
it('should handle metadata and mark recording as finished', () => {
|
|
291
|
+
// Get the actual UUID from the client
|
|
292
|
+
const actualUuid = simplifiedClient.getVGFState().audioUtteranceId;
|
|
293
|
+
|
|
232
294
|
const metadata = {
|
|
233
|
-
audioUtteranceId:
|
|
295
|
+
audioUtteranceId: actualUuid,
|
|
234
296
|
duration: 5000
|
|
235
297
|
};
|
|
236
298
|
|
|
@@ -387,9 +449,22 @@ describe('SimplifiedVGFRecognitionClient', () => {
|
|
|
387
449
|
|
|
388
450
|
describe('Thin Layer Verification', () => {
|
|
389
451
|
it('should pass transcript result directly to mapper without modification', () => {
|
|
452
|
+
simplifiedClient = new SimplifiedVGFRecognitionClient({
|
|
453
|
+
asrRequestConfig: {
|
|
454
|
+
provider: 'deepgram',
|
|
455
|
+
language: 'en',
|
|
456
|
+
sampleRate: 16000,
|
|
457
|
+
encoding: AudioEncoding.LINEAR16
|
|
458
|
+
},
|
|
459
|
+
onStateChange: stateChangeCallback
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
// Get actual UUID from client
|
|
463
|
+
const actualUuid = simplifiedClient.getVGFState().audioUtteranceId;
|
|
464
|
+
|
|
390
465
|
const transcriptResult = {
|
|
391
466
|
type: 'Transcription',
|
|
392
|
-
audioUtteranceId:
|
|
467
|
+
audioUtteranceId: actualUuid,
|
|
393
468
|
finalTranscript: 'Final text',
|
|
394
469
|
pendingTranscript: 'Pending text',
|
|
395
470
|
finalTranscriptConfidence: 0.99,
|
|
@@ -401,16 +476,6 @@ describe('SimplifiedVGFRecognitionClient', () => {
|
|
|
401
476
|
extraField: 'should be ignored by VGF state'
|
|
402
477
|
};
|
|
403
478
|
|
|
404
|
-
simplifiedClient = new SimplifiedVGFRecognitionClient({
|
|
405
|
-
asrRequestConfig: {
|
|
406
|
-
provider: 'deepgram',
|
|
407
|
-
language: 'en',
|
|
408
|
-
sampleRate: 16000,
|
|
409
|
-
encoding: AudioEncoding.LINEAR16
|
|
410
|
-
},
|
|
411
|
-
onStateChange: stateChangeCallback
|
|
412
|
-
});
|
|
413
|
-
|
|
414
479
|
const constructorCall = (RealTimeTwoWayWebSocketRecognitionClient as jest.MockedClass<typeof RealTimeTwoWayWebSocketRecognitionClient>).mock.calls[0]?.[0];
|
|
415
480
|
const wrappedCallback = constructorCall?.onTranscript;
|
|
416
481
|
if (!wrappedCallback) throw new Error('onTranscript callback not found');
|
|
@@ -1049,4 +1114,221 @@ describe('SimplifiedVGFRecognitionClient', () => {
|
|
|
1049
1114
|
});
|
|
1050
1115
|
});
|
|
1051
1116
|
});
|
|
1117
|
+
|
|
1118
|
+
describe('UUID Change Detection', () => {
|
|
1119
|
+
it('should skip onStateChange callback when UUID changes by default', () => {
|
|
1120
|
+
// Create client with initial state
|
|
1121
|
+
const initialState: RecognitionState = {
|
|
1122
|
+
audioUtteranceId: 'session-123',
|
|
1123
|
+
startRecordingStatus: RecordingStatus.READY,
|
|
1124
|
+
transcriptionStatus: TranscriptionStatus.NOT_STARTED,
|
|
1125
|
+
pendingTranscript: ''
|
|
1126
|
+
};
|
|
1127
|
+
|
|
1128
|
+
simplifiedClient = new SimplifiedVGFRecognitionClient({
|
|
1129
|
+
initialState,
|
|
1130
|
+
asrRequestConfig: {
|
|
1131
|
+
provider: 'deepgram',
|
|
1132
|
+
language: 'en',
|
|
1133
|
+
sampleRate: 16000,
|
|
1134
|
+
encoding: AudioEncoding.LINEAR16
|
|
1135
|
+
},
|
|
1136
|
+
onStateChange: stateChangeCallback
|
|
1137
|
+
});
|
|
1138
|
+
|
|
1139
|
+
// Get the callbacks that were passed to the underlying client
|
|
1140
|
+
const constructorCalls = (RealTimeTwoWayWebSocketRecognitionClient as jest.MockedClass<typeof RealTimeTwoWayWebSocketRecognitionClient>).mock.calls;
|
|
1141
|
+
const clientConfig = constructorCalls[0]?.[0];
|
|
1142
|
+
const onTranscriptCallback = clientConfig?.onTranscript;
|
|
1143
|
+
|
|
1144
|
+
// Simulate transcript with a different UUID (stale callback from previous session)
|
|
1145
|
+
onTranscriptCallback?.({
|
|
1146
|
+
type: 'transcript',
|
|
1147
|
+
is_finished: false,
|
|
1148
|
+
pendingTranscript: 'test transcript',
|
|
1149
|
+
audioUtteranceId: 'different-uuid-456' // Different UUID
|
|
1150
|
+
} as any);
|
|
1151
|
+
|
|
1152
|
+
// State should NOT be updated - callback should be skipped
|
|
1153
|
+
expect(stateChangeCallback).not.toHaveBeenCalled();
|
|
1154
|
+
|
|
1155
|
+
// Internal state should still have original UUID
|
|
1156
|
+
const state = simplifiedClient.getVGFState();
|
|
1157
|
+
expect(state.audioUtteranceId).toBe('session-123');
|
|
1158
|
+
expect(state.pendingTranscript).toBe(''); // Not updated
|
|
1159
|
+
});
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
it('should process callbacks with matching UUID', () => {
|
|
1163
|
+
// Create client with initial state
|
|
1164
|
+
const initialState: RecognitionState = {
|
|
1165
|
+
audioUtteranceId: 'session-123',
|
|
1166
|
+
startRecordingStatus: RecordingStatus.READY,
|
|
1167
|
+
transcriptionStatus: TranscriptionStatus.NOT_STARTED,
|
|
1168
|
+
pendingTranscript: ''
|
|
1169
|
+
};
|
|
1170
|
+
|
|
1171
|
+
simplifiedClient = new SimplifiedVGFRecognitionClient({
|
|
1172
|
+
initialState,
|
|
1173
|
+
asrRequestConfig: {
|
|
1174
|
+
provider: 'deepgram',
|
|
1175
|
+
language: 'en',
|
|
1176
|
+
sampleRate: 16000,
|
|
1177
|
+
encoding: AudioEncoding.LINEAR16
|
|
1178
|
+
},
|
|
1179
|
+
onStateChange: stateChangeCallback
|
|
1180
|
+
});
|
|
1181
|
+
|
|
1182
|
+
// Get the callbacks that were passed to the underlying client
|
|
1183
|
+
const constructorCalls = (RealTimeTwoWayWebSocketRecognitionClient as jest.MockedClass<typeof RealTimeTwoWayWebSocketRecognitionClient>).mock.calls;
|
|
1184
|
+
const clientConfig = constructorCalls[0]?.[0];
|
|
1185
|
+
const onTranscriptCallback = clientConfig?.onTranscript;
|
|
1186
|
+
|
|
1187
|
+
// Simulate transcript with matching UUID
|
|
1188
|
+
onTranscriptCallback?.({
|
|
1189
|
+
type: 'transcript',
|
|
1190
|
+
is_finished: false,
|
|
1191
|
+
pendingTranscript: 'test transcript',
|
|
1192
|
+
audioUtteranceId: 'session-123' // Same UUID
|
|
1193
|
+
} as any);
|
|
1194
|
+
|
|
1195
|
+
// State should be updated normally
|
|
1196
|
+
expect(stateChangeCallback).toHaveBeenCalledTimes(1);
|
|
1197
|
+
const updatedState = stateChangeCallback.mock.calls[0][0];
|
|
1198
|
+
expect(updatedState.audioUtteranceId).toBe('session-123');
|
|
1199
|
+
expect(updatedState.pendingTranscript).toBe('test transcript');
|
|
1200
|
+
});
|
|
1201
|
+
|
|
1202
|
+
it('should skip metadata callback with different UUID', () => {
|
|
1203
|
+
// Create client with initial state
|
|
1204
|
+
const initialState: RecognitionState = {
|
|
1205
|
+
audioUtteranceId: 'session-123',
|
|
1206
|
+
startRecordingStatus: RecordingStatus.READY,
|
|
1207
|
+
transcriptionStatus: TranscriptionStatus.NOT_STARTED,
|
|
1208
|
+
pendingTranscript: ''
|
|
1209
|
+
};
|
|
1210
|
+
|
|
1211
|
+
simplifiedClient = new SimplifiedVGFRecognitionClient({
|
|
1212
|
+
initialState,
|
|
1213
|
+
asrRequestConfig: {
|
|
1214
|
+
provider: 'deepgram',
|
|
1215
|
+
language: 'en',
|
|
1216
|
+
sampleRate: 16000,
|
|
1217
|
+
encoding: AudioEncoding.LINEAR16
|
|
1218
|
+
},
|
|
1219
|
+
onStateChange: stateChangeCallback
|
|
1220
|
+
});
|
|
1221
|
+
|
|
1222
|
+
// Get the metadata callback
|
|
1223
|
+
const constructorCalls = (RealTimeTwoWayWebSocketRecognitionClient as jest.MockedClass<typeof RealTimeTwoWayWebSocketRecognitionClient>).mock.calls;
|
|
1224
|
+
const clientConfig = constructorCalls[0]?.[0];
|
|
1225
|
+
const onMetadataCallback = clientConfig?.onMetadata;
|
|
1226
|
+
|
|
1227
|
+
// Simulate metadata with different UUID
|
|
1228
|
+
onMetadataCallback?.({
|
|
1229
|
+
type: 'metadata',
|
|
1230
|
+
event: 'recording_stopped',
|
|
1231
|
+
audioUtteranceId: 'different-uuid-456'
|
|
1232
|
+
} as any);
|
|
1233
|
+
|
|
1234
|
+
// Callback should be skipped
|
|
1235
|
+
expect(stateChangeCallback).not.toHaveBeenCalled();
|
|
1236
|
+
});
|
|
1237
|
+
|
|
1238
|
+
it('should skip error callback with different UUID', () => {
|
|
1239
|
+
// Create client with initial state
|
|
1240
|
+
const initialState: RecognitionState = {
|
|
1241
|
+
audioUtteranceId: 'session-123',
|
|
1242
|
+
startRecordingStatus: RecordingStatus.READY,
|
|
1243
|
+
transcriptionStatus: TranscriptionStatus.NOT_STARTED,
|
|
1244
|
+
pendingTranscript: ''
|
|
1245
|
+
};
|
|
1246
|
+
|
|
1247
|
+
simplifiedClient = new SimplifiedVGFRecognitionClient({
|
|
1248
|
+
initialState,
|
|
1249
|
+
asrRequestConfig: {
|
|
1250
|
+
provider: 'deepgram',
|
|
1251
|
+
language: 'en',
|
|
1252
|
+
sampleRate: 16000,
|
|
1253
|
+
encoding: AudioEncoding.LINEAR16
|
|
1254
|
+
},
|
|
1255
|
+
onStateChange: stateChangeCallback
|
|
1256
|
+
});
|
|
1257
|
+
|
|
1258
|
+
// Get the error callback
|
|
1259
|
+
const constructorCalls = (RealTimeTwoWayWebSocketRecognitionClient as jest.MockedClass<typeof RealTimeTwoWayWebSocketRecognitionClient>).mock.calls;
|
|
1260
|
+
const clientConfig = constructorCalls[0]?.[0];
|
|
1261
|
+
const onErrorCallback = clientConfig?.onError;
|
|
1262
|
+
|
|
1263
|
+
// Simulate error with different UUID
|
|
1264
|
+
onErrorCallback?.({
|
|
1265
|
+
type: 'error',
|
|
1266
|
+
error: 'test error',
|
|
1267
|
+
audioUtteranceId: 'different-uuid-456'
|
|
1268
|
+
} as any);
|
|
1269
|
+
|
|
1270
|
+
// Callback should be skipped
|
|
1271
|
+
expect(stateChangeCallback).not.toHaveBeenCalled();
|
|
1272
|
+
});
|
|
1273
|
+
|
|
1274
|
+
it('should track UUID after terminal state regeneration', () => {
|
|
1275
|
+
// Create client with terminal initial state (forces UUID regeneration)
|
|
1276
|
+
const initialState: RecognitionState = {
|
|
1277
|
+
audioUtteranceId: 'old-session-123',
|
|
1278
|
+
startRecordingStatus: RecordingStatus.FINISHED,
|
|
1279
|
+
transcriptionStatus: TranscriptionStatus.FINALIZED, // Terminal state
|
|
1280
|
+
pendingTranscript: '',
|
|
1281
|
+
finalTranscript: 'Previous transcript'
|
|
1282
|
+
};
|
|
1283
|
+
|
|
1284
|
+
simplifiedClient = new SimplifiedVGFRecognitionClient({
|
|
1285
|
+
initialState,
|
|
1286
|
+
asrRequestConfig: {
|
|
1287
|
+
provider: 'deepgram',
|
|
1288
|
+
language: 'en',
|
|
1289
|
+
sampleRate: 16000,
|
|
1290
|
+
encoding: AudioEncoding.LINEAR16
|
|
1291
|
+
},
|
|
1292
|
+
onStateChange: stateChangeCallback
|
|
1293
|
+
});
|
|
1294
|
+
|
|
1295
|
+
// Get the new UUID that was generated
|
|
1296
|
+
const newState = simplifiedClient.getVGFState();
|
|
1297
|
+
const newUuid = newState.audioUtteranceId;
|
|
1298
|
+
expect(newUuid).not.toBe('old-session-123');
|
|
1299
|
+
|
|
1300
|
+
// Get the transcript callback
|
|
1301
|
+
const constructorCalls = (RealTimeTwoWayWebSocketRecognitionClient as jest.MockedClass<typeof RealTimeTwoWayWebSocketRecognitionClient>).mock.calls;
|
|
1302
|
+
const clientConfig = constructorCalls[0]?.[0];
|
|
1303
|
+
const onTranscriptCallback = clientConfig?.onTranscript;
|
|
1304
|
+
|
|
1305
|
+
// Clear initial state change callback from UUID regeneration
|
|
1306
|
+
jest.clearAllMocks();
|
|
1307
|
+
|
|
1308
|
+
// Simulate transcript with the NEW UUID
|
|
1309
|
+
onTranscriptCallback?.({
|
|
1310
|
+
type: 'transcript',
|
|
1311
|
+
is_finished: false,
|
|
1312
|
+
pendingTranscript: 'new transcript',
|
|
1313
|
+
audioUtteranceId: newUuid // New UUID
|
|
1314
|
+
} as any);
|
|
1315
|
+
|
|
1316
|
+
// Should process normally with new UUID
|
|
1317
|
+
expect(stateChangeCallback).toHaveBeenCalledTimes(1);
|
|
1318
|
+
const updatedState = stateChangeCallback.mock.calls[0][0];
|
|
1319
|
+
expect(updatedState.pendingTranscript).toBe('new transcript');
|
|
1320
|
+
|
|
1321
|
+
// Simulate transcript with OLD UUID (stale callback)
|
|
1322
|
+
jest.clearAllMocks();
|
|
1323
|
+
onTranscriptCallback?.({
|
|
1324
|
+
type: 'transcript',
|
|
1325
|
+
is_finished: false,
|
|
1326
|
+
pendingTranscript: 'stale transcript',
|
|
1327
|
+
audioUtteranceId: 'old-session-123' // Old UUID
|
|
1328
|
+
} as any);
|
|
1329
|
+
|
|
1330
|
+
// Should skip callback with old UUID
|
|
1331
|
+
expect(stateChangeCallback).not.toHaveBeenCalled();
|
|
1332
|
+
});
|
|
1333
|
+
});
|
|
1052
1334
|
});
|