@volley/recognition-client-sdk 0.1.255 → 0.1.287

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.
Files changed (38) hide show
  1. package/dist/browser.d.ts +10 -0
  2. package/dist/browser.d.ts.map +1 -0
  3. package/dist/config-builder.d.ts +129 -0
  4. package/dist/config-builder.d.ts.map +1 -0
  5. package/dist/errors.d.ts +41 -0
  6. package/dist/errors.d.ts.map +1 -0
  7. package/dist/factory.d.ts +36 -0
  8. package/dist/factory.d.ts.map +1 -0
  9. package/dist/index.d.ts +15 -1079
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +9760 -2109
  12. package/dist/index.js.map +7 -1
  13. package/dist/recog-client-sdk.browser.d.ts +10 -2
  14. package/dist/recog-client-sdk.browser.d.ts.map +1 -0
  15. package/dist/recog-client-sdk.browser.js +4597 -701
  16. package/dist/recog-client-sdk.browser.js.map +7 -1
  17. package/dist/recognition-client.d.ts +119 -0
  18. package/dist/recognition-client.d.ts.map +1 -0
  19. package/dist/recognition-client.types.d.ts +247 -0
  20. package/dist/recognition-client.types.d.ts.map +1 -0
  21. package/dist/simplified-vgf-recognition-client.d.ts +155 -0
  22. package/dist/simplified-vgf-recognition-client.d.ts.map +1 -0
  23. package/dist/utils/audio-ring-buffer.d.ts +69 -0
  24. package/dist/utils/audio-ring-buffer.d.ts.map +1 -0
  25. package/dist/utils/message-handler.d.ts +45 -0
  26. package/dist/utils/message-handler.d.ts.map +1 -0
  27. package/dist/utils/url-builder.d.ts +26 -0
  28. package/dist/utils/url-builder.d.ts.map +1 -0
  29. package/dist/vgf-recognition-mapper.d.ts +53 -0
  30. package/dist/vgf-recognition-mapper.d.ts.map +1 -0
  31. package/dist/vgf-recognition-state.d.ts +81 -0
  32. package/dist/vgf-recognition-state.d.ts.map +1 -0
  33. package/package.json +7 -8
  34. package/src/index.ts +4 -0
  35. package/src/recognition-client.spec.ts +19 -14
  36. package/src/recognition-client.ts +4 -0
  37. package/src/utils/url-builder.spec.ts +5 -3
  38. package/dist/browser-BZs4BL_w.d.ts +0 -1118
@@ -0,0 +1,26 @@
1
+ /**
2
+ * URL Builder for Recognition Client
3
+ * Handles WebSocket URL construction with query parameters
4
+ */
5
+ import type { GameContextV1, Stage } from '@recog/shared-types';
6
+ import type { RecognitionCallbackUrl } from '../recognition-client.types.js';
7
+ export interface UrlBuilderConfig {
8
+ url?: string;
9
+ stage?: Stage | string;
10
+ audioUtteranceId: string;
11
+ callbackUrls?: RecognitionCallbackUrl[];
12
+ userId?: string;
13
+ gameSessionId?: string;
14
+ deviceId?: string;
15
+ accountId?: string;
16
+ questionAnswerId?: string;
17
+ platform?: string;
18
+ gameContext?: GameContextV1;
19
+ }
20
+ /**
21
+ * Build WebSocket URL with all query parameters
22
+ * Either `url` or `stage` must be provided (or defaults to production if neither provided)
23
+ * If both are provided, `url` takes precedence over `stage`
24
+ */
25
+ export declare function buildWebSocketUrl(config: UrlBuilderConfig): string;
26
+ //# sourceMappingURL=url-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-builder.d.ts","sourceRoot":"","sources":["../../src/utils/url-builder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAE7E,MAAM,WAAW,gBAAgB;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,aAAa,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAwDlE"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * VGF Recognition Mapper
3
+ *
4
+ * Maps between the existing recognition client types and the simplified VGF state.
5
+ * This provides a clean abstraction layer for game developers.
6
+ */
7
+ import { RecognitionState } from './vgf-recognition-state.js';
8
+ import { ClientState, IRecognitionClientConfig } from './recognition-client.types.js';
9
+ import { TranscriptionResultV1, MetadataResultV1, ErrorResultV1 } from '@recog/shared-types';
10
+ /**
11
+ * Maps ClientState to RecordingStatus for VGF state
12
+ */
13
+ export declare function mapClientStateToRecordingStatus(clientState: ClientState): string;
14
+ /**
15
+ * Creates a VGF state from transcription result
16
+ */
17
+ export declare function mapTranscriptionResultToState(currentState: RecognitionState, result: TranscriptionResultV1, isRecording: boolean): RecognitionState;
18
+ /**
19
+ * Maps metadata result to update state timestamps
20
+ */
21
+ export declare function mapMetadataToState(currentState: RecognitionState, metadata: MetadataResultV1): RecognitionState;
22
+ /**
23
+ * Maps error to state
24
+ */
25
+ export declare function mapErrorToState(currentState: RecognitionState, error: ErrorResultV1): RecognitionState;
26
+ /**
27
+ * Creates initial VGF state from client config
28
+ */
29
+ export declare function createVGFStateFromConfig(config: IRecognitionClientConfig): RecognitionState;
30
+ /**
31
+ * Updates state when recording stops
32
+ */
33
+ export declare function updateStateOnStop(currentState: RecognitionState): RecognitionState;
34
+ /**
35
+ * Updates state when client becomes ready
36
+ */
37
+ export declare function updateStateOnReady(currentState: RecognitionState): RecognitionState;
38
+ /**
39
+ * Parses function call from transcript (STEP 3 support)
40
+ * This is a placeholder - actual implementation would use NLP/LLM
41
+ */
42
+ export declare function extractFunctionCallFromTranscript(transcript: string, gameContext?: any): {
43
+ metadata?: string;
44
+ confidence?: number;
45
+ } | null;
46
+ /**
47
+ * Updates state with function call results (STEP 3)
48
+ */
49
+ export declare function updateStateWithFunctionCall(currentState: RecognitionState, functionCall: {
50
+ metadata?: string;
51
+ confidence?: number;
52
+ }): RecognitionState;
53
+ //# sourceMappingURL=vgf-recognition-mapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgf-recognition-mapper.d.ts","sourceRoot":"","sources":["../src/vgf-recognition-mapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACH,gBAAgB,EAInB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACH,WAAW,EACX,wBAAwB,EAC3B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACH,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EAEhB,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,wBAAgB,+BAA+B,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAmBhF;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CACzC,YAAY,EAAE,gBAAgB,EAC9B,MAAM,EAAE,qBAAqB,EAC7B,WAAW,EAAE,OAAO,GACrB,gBAAgB,CAgDlB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAC9B,YAAY,EAAE,gBAAgB,EAC9B,QAAQ,EAAE,gBAAgB,GAC3B,gBAAgB,CAYlB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC3B,YAAY,EAAE,gBAAgB,EAC9B,KAAK,EAAE,aAAa,GACrB,gBAAgB,CAOlB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,wBAAwB,GAAG,gBAAgB,CAU3F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,gBAAgB,GAAG,gBAAgB,CAMlF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,gBAAgB,GAAG,gBAAgB,CAKnF;AAED;;;GAGG;AACH,wBAAgB,iCAAiC,CAC7C,UAAU,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,GAAG,GAClB;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiBnD;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACvC,YAAY,EAAE,gBAAgB,EAC9B,YAAY,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACzD,gBAAgB,CAOlB"}
@@ -0,0 +1,81 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * VGF-style state schema for game-side recognition state/results management.
4
+ *
5
+ * This schema provides a standardized way for game developers to manage
6
+ * voice recognition state and results in their applications. It supports:
7
+ *
8
+ * STEP 1: Basic transcription flow
9
+ * STEP 2: Mic auto-stop upon correct answer (using partial transcripts)
10
+ * STEP 3: Semantic/function-call outcomes for game actions
11
+ *
12
+ * Ideally this should be part of a more centralized shared type library to free
13
+ * game developers and provide helper functions (VGF? Platform SDK?).
14
+ */
15
+ export declare const RecognitionVGFStateSchema: z.ZodObject<{
16
+ audioUtteranceId: z.ZodString;
17
+ startRecordingStatus: z.ZodOptional<z.ZodString>;
18
+ transcriptionStatus: z.ZodOptional<z.ZodString>;
19
+ finalTranscript: z.ZodOptional<z.ZodString>;
20
+ finalConfidence: z.ZodOptional<z.ZodNumber>;
21
+ asrConfig: z.ZodOptional<z.ZodString>;
22
+ startRecordingTimestamp: z.ZodOptional<z.ZodString>;
23
+ finalRecordingTimestamp: z.ZodOptional<z.ZodString>;
24
+ finalTranscriptionTimestamp: z.ZodOptional<z.ZodString>;
25
+ pendingTranscript: z.ZodDefault<z.ZodOptional<z.ZodString>>;
26
+ pendingConfidence: z.ZodOptional<z.ZodNumber>;
27
+ functionCallMetadata: z.ZodOptional<z.ZodString>;
28
+ functionCallConfidence: z.ZodOptional<z.ZodNumber>;
29
+ finalFunctionCallTimestamp: z.ZodOptional<z.ZodString>;
30
+ promptSlotMap: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
31
+ }, "strip", z.ZodTypeAny, {
32
+ audioUtteranceId: string;
33
+ pendingTranscript: string;
34
+ startRecordingStatus?: string | undefined;
35
+ transcriptionStatus?: string | undefined;
36
+ finalTranscript?: string | undefined;
37
+ finalConfidence?: number | undefined;
38
+ asrConfig?: string | undefined;
39
+ startRecordingTimestamp?: string | undefined;
40
+ finalRecordingTimestamp?: string | undefined;
41
+ finalTranscriptionTimestamp?: string | undefined;
42
+ pendingConfidence?: number | undefined;
43
+ functionCallMetadata?: string | undefined;
44
+ functionCallConfidence?: number | undefined;
45
+ finalFunctionCallTimestamp?: string | undefined;
46
+ promptSlotMap?: Record<string, string[]> | undefined;
47
+ }, {
48
+ audioUtteranceId: string;
49
+ startRecordingStatus?: string | undefined;
50
+ transcriptionStatus?: string | undefined;
51
+ finalTranscript?: string | undefined;
52
+ finalConfidence?: number | undefined;
53
+ asrConfig?: string | undefined;
54
+ startRecordingTimestamp?: string | undefined;
55
+ finalRecordingTimestamp?: string | undefined;
56
+ finalTranscriptionTimestamp?: string | undefined;
57
+ pendingTranscript?: string | undefined;
58
+ pendingConfidence?: number | undefined;
59
+ functionCallMetadata?: string | undefined;
60
+ functionCallConfidence?: number | undefined;
61
+ finalFunctionCallTimestamp?: string | undefined;
62
+ promptSlotMap?: Record<string, string[]> | undefined;
63
+ }>;
64
+ export type RecognitionState = z.infer<typeof RecognitionVGFStateSchema>;
65
+ export declare const RecordingStatus: {
66
+ readonly NOT_READY: "NOT_READY";
67
+ readonly READY: "READY";
68
+ readonly RECORDING: "RECORDING";
69
+ readonly FINISHED: "FINISHED";
70
+ };
71
+ export type RecordingStatusType = typeof RecordingStatus[keyof typeof RecordingStatus];
72
+ export declare const TranscriptionStatus: {
73
+ readonly NOT_STARTED: "NOT_STARTED";
74
+ readonly IN_PROGRESS: "IN_PROGRESS";
75
+ readonly FINALIZED: "FINALIZED";
76
+ readonly ERROR: "ERROR";
77
+ };
78
+ export type TranscriptionStatusType = typeof TranscriptionStatus[keyof typeof TranscriptionStatus];
79
+ export declare function createInitialRecognitionState(audioUtteranceId: string): RecognitionState;
80
+ export declare function isValidRecordingStatusTransition(from: string | undefined, to: string): boolean;
81
+ //# sourceMappingURL=vgf-recognition-state.d.ts.map
@@ -0,0 +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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BpC,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;;;;;CAKtB,CAAA;AAEV,MAAM,MAAM,uBAAuB,GAAG,OAAO,mBAAmB,CAAC,MAAM,OAAO,mBAAmB,CAAC,CAAA;AAGlG,wBAAgB,6BAA6B,CAAC,gBAAgB,EAAE,MAAM,GAAG,gBAAgB,CAOxF;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.255",
3
+ "version": "0.1.287",
4
4
  "description": "Recognition Service TypeScript/Node.js Client SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,8 +32,8 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "uuid": "^11.0.0",
35
- "ws": "^8.13.0",
36
- "zod": "^3.22.4"
35
+ "ws": "8.18.3",
36
+ "zod": "~3.22.4"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@semantic-release/changelog": "^6.0.3",
@@ -51,12 +51,11 @@
51
51
  "jest": "^29.6.1",
52
52
  "semantic-release": "^25.0.1",
53
53
  "ts-jest": "^29.4.5",
54
- "tsup": "^8.5.0",
55
54
  "typescript": "^5.1.6",
56
55
  "@recog/shared-config": "1.0.0",
57
- "@recog/websocket": "1.0.0",
58
56
  "@recog/shared-utils": "1.0.0",
59
- "@recog/shared-types": "1.0.0"
57
+ "@recog/shared-types": "1.0.0",
58
+ "@recog/websocket": "1.0.0"
60
59
  },
61
60
  "keywords": [
62
61
  "recognition",
@@ -65,8 +64,8 @@
65
64
  "speech"
66
65
  ],
67
66
  "scripts": {
68
- "build": "tsup",
69
- "dev": "tsup --watch",
67
+ "build": "node build.mjs",
68
+ "dev": "node build.mjs --watch",
70
69
  "test": "jest --passWithNoTests",
71
70
  "lint": "eslint src --ext .ts"
72
71
  }
package/src/index.ts CHANGED
@@ -76,6 +76,7 @@ export { AudioEncoding } from '@recog/websocket';
76
76
  export {
77
77
  // Recognition context types
78
78
  type GameContextV1,
79
+ type SlotMap,
79
80
  RecognitionContextTypeV1,
80
81
  ControlSignalTypeV1,
81
82
  ControlSignalTypeV1 as ControlSignal, // Alias for backward compatibility
@@ -86,10 +87,13 @@ export {
86
87
  type MetadataResultV1,
87
88
  type ErrorResultV1,
88
89
  RecognitionResultTypeV1,
90
+ ClientControlActionV1,
89
91
 
90
92
  // ASR configuration types
91
93
  type ASRRequestConfig,
92
94
  type ASRRequestV1,
95
+ FinalTranscriptStability,
96
+ createDefaultASRConfig,
93
97
  RecognitionProvider,
94
98
  DeepgramModel,
95
99
  GoogleModel,
@@ -581,12 +581,14 @@ describe('RealTimeTwoWayWebSocketRecognitionClient', () => {
581
581
  logger: mockLogger
582
582
  });
583
583
 
584
- // Create a mock Blob that throws on arrayBuffer()
585
- const badBlob: any = {
586
- arrayBuffer: jest.fn().mockRejectedValue(new Error('Conversion failed'))
587
- };
584
+ // Create a real Blob but spy on arrayBuffer to make it fail
585
+ const audioData = new Uint8Array([1, 2, 3, 4]);
586
+ const badBlob = new Blob([audioData], { type: 'audio/raw' });
587
+
588
+ // Mock arrayBuffer to reject
589
+ jest.spyOn(badBlob, 'arrayBuffer').mockRejectedValue(new Error('Conversion failed'));
588
590
 
589
- testClient.sendAudio(badBlob as Blob);
591
+ testClient.sendAudio(badBlob);
590
592
 
591
593
  // Wait for error handling
592
594
  await new Promise(resolve => setTimeout(resolve, 100));
@@ -623,14 +625,10 @@ describe('RealTimeTwoWayWebSocketRecognitionClient', () => {
623
625
  it('should use FileReader fallback when blob.arrayBuffer not available (Smart TV path)', async () => {
624
626
  const audioData = new Uint8Array([1, 2, 3, 4]);
625
627
 
626
- // Create a mock Blob-like object without arrayBuffer (simulates old Smart TV)
627
- const blobLike = {
628
- size: audioData.length,
629
- type: 'audio/raw',
630
- // No arrayBuffer method - will trigger FileReader path
631
- };
628
+ // Create a real Blob
629
+ const blob = new Blob([audioData], { type: 'audio/raw' });
632
630
 
633
- // Mock FileReader
631
+ // Mock FileReader BEFORE removing arrayBuffer
634
632
  const mockReadAsArrayBuffer = jest.fn();
635
633
  const originalFileReader = (global as any).FileReader;
636
634
 
@@ -651,14 +649,21 @@ describe('RealTimeTwoWayWebSocketRecognitionClient', () => {
651
649
  }, 10);
652
650
  });
653
651
 
654
- client.sendAudio(blobLike as Blob);
652
+ // Remove arrayBuffer method to simulate old Smart TV (must be done after blob creation)
653
+ Object.defineProperty(blob, 'arrayBuffer', {
654
+ value: undefined,
655
+ writable: true,
656
+ configurable: true
657
+ });
658
+
659
+ client.sendAudio(blob);
655
660
 
656
661
  // Wait for FileReader async conversion
657
662
  await new Promise(resolve => setTimeout(resolve, 150));
658
663
 
659
664
  // Should have used FileReader
660
665
  expect((global as any).FileReader).toHaveBeenCalled();
661
- expect(mockReadAsArrayBuffer).toHaveBeenCalledWith(blobLike);
666
+ expect(mockReadAsArrayBuffer).toHaveBeenCalledWith(blob);
662
667
 
663
668
  // Should have buffered successfully
664
669
  const stats = client.getStats();
@@ -627,6 +627,10 @@ export class RealTimeTwoWayWebSocketRecognitionClient
627
627
  interimResults: this.config.asrRequestConfig.interimResults ?? false,
628
628
  // Auto-enable useContext if gameContext is provided, or use explicit value if set
629
629
  useContext: this.config.asrRequestConfig.useContext ?? !!this.config.gameContext,
630
+ // Include finalTranscriptStability if provided (it's already a string enum)
631
+ ...(this.config.asrRequestConfig.finalTranscriptStability && {
632
+ finalTranscriptStability: this.config.asrRequestConfig.finalTranscriptStability
633
+ }),
630
634
  ...(debugCommand && { debugCommand })
631
635
  };
632
636
 
@@ -2,22 +2,24 @@
2
2
  * Unit tests for URL Builder
3
3
  */
4
4
 
5
- import { buildWebSocketUrl, UrlBuilderConfig } from './url-builder.js';
6
5
  import { RecognitionContextTypeV1, STAGES } from '@recog/shared-types';
7
6
 
8
- // Mock the shared-config module
7
+ // Mock the shared-config module BEFORE importing the module under test
9
8
  const mockGetRecognitionServiceBase = jest.fn();
10
9
  jest.mock('@recog/shared-config', () => ({
11
10
  getRecognitionServiceBase: mockGetRecognitionServiceBase
12
11
  }));
13
12
 
13
+ import { buildWebSocketUrl, UrlBuilderConfig } from './url-builder.js';
14
+
14
15
  describe('buildWebSocketUrl', () => {
15
16
  const baseConfig: UrlBuilderConfig = {
16
17
  audioUtteranceId: 'test-utterance-123'
17
18
  };
18
19
 
19
20
  beforeEach(() => {
20
- // Reset mock before each test
21
+ // Clear and reset mock before each test
22
+ mockGetRecognitionServiceBase.mockClear();
21
23
  mockGetRecognitionServiceBase.mockReturnValue({
22
24
  wsBase: 'wss://recognition.volley.com'
23
25
  });